除模板之外是否还有任何C++元编程替代方案?

问题描述:

我一直在使用metaprogramming,但有时候c宏和模板的组合还不够。除模板之外是否还有任何C++元编程替代方案?

我想缺点将可能是缺乏跨平台的兼容性,如果元编程平台是唯一的,比如说,Linux的等

所以呀,有没有可用的这样的事情,现在,除了模板?谷歌搜索元编程主要是模板metaprogramming,所以现在很难找到..

编辑:这是我一直在努力的一个例子。

假设我有一个通用类来保存/加载缓冲区中的文件。我们称之为FilePack。

我有一个定义的宏,它看起来像

defineFilePack(BaseClass, "code-a") 

它基本上创建了一个名为“BaseClassPack”类,它被定义为一个子类。下面是那个东西。

class FilePack{ 
    public: 
     char * thebuffer; 
     int bufsize; 
     string packcode; 

     // and constructors etc 
     FilePack(const string& thecode, int bufsize); 
     void operator=(FilePack& rhs); 
     void saveToFile(const string& filename); 
     void loadFromFile(const string& filename); 
     // .. and all the function you'd expect to see in a class like this 

}; 

// the person details 

class PersonDetails{ 
    public: 
     solidstring<64> name; 
     int age; 
     DateTime birthday; 
     // .. yada yada yada 
}; 


defineFilePack(PersonDetails, "psd") 

// the above creates the following class 

class PersonDetailsPack : public FilePack{ 
    public: 
     PersonDetailsPack(): 
     FilePack("psd", sizeof(PersonDetails)){ // etc 

     } 

     PersonDetails& get(){ 
     return *(PersonDetails*)getBuffer(); 
     } 

     // and a lot more convenience function 

}; 

现在,实际上是由FilePack的构造一个内置的检查申报代码尺寸相匹配,采用了全球地图。

现在我很难理解如何使用模板元编程,它实际上非常适合它,因为所有这些filepack代码都是在源文件中声明的。当然,有人可能会在运行时创建自己的FilePack,但那不是重点。

元编程可以帮助的另一件事是支持加载不同版本的FilePack。假设我必须更新PersonDetails类。我只是创建一个新类,使用某种元编程来声明继承,并且神奇地让FilePack知道,以便在加载旧版本的PersonDetails时可以调用转换函数,或者随你。

此外,欢迎您对该架构发表评论,并且我很乐意听到关于它的任何评论,但它可能有点偏离主题?

+0

你能提供一个模板+宏不够的例子吗?这将是讨论的一个好的起点。 – 2011-01-11 20:14:05

+2

@David Rodriguez:例如,生成通过网络连接序列化类的代码,或者通常为每个成员做些事情。 – 6502 2011-01-11 20:15:43

+0

“,但是有时候c宏和模板的组合不够” - 什么是缺失/不够? – Naveen 2011-01-11 20:15:47

您也可以使用预处理器进行元编程。

你也可以考虑使用专用预处理器来生成代码作为“元编程”。然后你可以包含诸如lex/yacc和Qt MOC之类的东西。

我认为这个工作对于Python来说是完美的。简单的方法是使用自定义文件格式来描述如何创建类,然后可以生成实现和接口(即使使用多种语言)。因为复杂的C++语法......(以及为什么要限制你自己想要表达的内容?),解析现有的C++头文件反而是一场噩梦。

Python是多平台和一个非常好的语言本身......

如下面的例子是我用的“增强” C++的例子...

// 
// U8 -> F32 format converter 
// 
// - src(Image:U8) ............ source image 
// - dst(pImage:F32:src) ...... destination image 
// 
ImgFilter u8_to_f32(Image& src, Image& dst) 
{ 
    const double k = 1.0/255; 
    for (int y=0; y<src.h; y++) 
    { 
     unsigned char *rp = src.u8(0, y); 
     float *wp = dst.f32(0, y); 
     for (int x=0,w=src.w; x<w; x++) 
      *wp++ = *rp++ * k; 
    } 
} 

功能和名称/参数上面的评论是由生成的.h该处理内存分配,大小和格式兼容性检查,命令行参数解析的函数,C++代码的Python脚本读取在线帮助和python绑定。 基本上我只能写“肉”,并为我生成所有的样板文件。这样做的python脚本是200行,并给定了生成的代码的数量C++样板只是几个过滤器已经超过了这一点。

在语言中,只能使用模板或宏来实现元程序。例如,Boost预处理程序库提供的元编程功能非常强大,它实现了一些真正令人惊叹的宏功能。

但是,如果您希望获得更多的信息,您可以使用您选择的脚本语言进行元编程。

如果你定义的元编程为编写代码生成的代码,那么你有

  • 模板。
  • 预处理器。
  • 其他预处理(通常是脚本,但有时编译器扩展)
  • 从C++代码生成C++源代码,实时编译,加载为共享库。
  • 可能,但这就是拉伸它,也会生成机器码,如蹦床存根。

我觉得最有意思的不是模板或C++预处理器,它是支持交叉编程的语言扩展,例如日志方法调用或序列化。

我记得ParcPlace为此做了一个工具吗?

嗯,这提醒我不要忘记检查一下,有时。 :-)

干杯&心连心,

如果要执行的代码随心所欲的操控,你想有一个通用的元编程工具,如程序变换系统。这些工具接受源代码,并使用类似编译器的技术根据您的需求对该代码进行任意分析/修改。

我们的 DMS Software Reengineering Toolkit就是这样一个系统。它通过对要处理的编程语言的明确描述以及希望它在源代码上执行的任务进行参数化。 DMS在这种通用方面是独一无二的(Jackpot是一个纯Java程序转换系统),并且在生产C++系统上用于大规模转换任务时具有强大的C++ Front End

对于前端,DMS可以解析源代码以抽象语法树,构建符号表,使用直接用C++术语编写的模式执行模式匹配或代码转换,并且使用注释和原始格式重新生成可编译源代码。文字(完整的数字基数等)。您的程序修改可以是您可以通过AST定义的任何计算。简言之,从语言之外,它可以做什么语言支持的元编程功能所不能做到的。