欢迎来到天天文库
浏览记录
ID:36291134
大小:256.50 KB
页数:52页
时间:2019-05-08
《c模板元编程技术与应用》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、C++模板元编程技术与应用荣耀royal@royaloo.comwww.royaloo.com动机让更多的C++程序员了解模板元编程,并在此过程中获得快乐!目录*历史*导入范例*主要思想*静态语言设施*控制结构*数据结构*数值计算*类型计算*代码生成*断言和契约*库*DSEL设计*结语*资源历史1994年,在圣迭哥举行的一次C++标准委员会会议期间,ErwinUnruh展示了一段特别的代码,可以在编译期以编译错误信息的方式产生从2到某个给定值之间的所有质数。这份代码的原始版本见[注5],修订版见[注6]。可以使用G
2、CC编译器观察到上述效果。同年夏天,ToddVeldhuizen受Erwin的例子启发,发现可以使用C++模板进行元编程(metaprogramming),并发表了一份技术报告。次年5月又在C++Report上发表了一篇名为“UsingC++templatemetaprograms”的文章,从而将ErwinUnruh发现的C++编译期模板编程(Compile-timeTemplateProgramming)进一步精化为C++模板元编程(TemplateMetaprogramming,TMP)。导入范例//主模板te
3、mplatestructFib{enum{Result=Fib::Result+Fib::Result};};//完全特化版template<>structFib<1>{enum{Result=1};};//完全特化版template<>structFib<0>{enum{Result=0};};1.计算Fibonacci数列第N项//示例intmain(){inti=Fib<10>::Result;//std::cout<4、=1的情况处理N=0的情况特化必须放在主模板之后导入范例语句inti=Fib<10>::Result;被VC7.1编译成如下指令(IntelP4CPU):00411A1Emovdwordptr[i],37h字面量37h即为Fibonacci数列的第10项的值。可见,Fib<10>::Result的确被评估于编译期,结果作为处理器指令的一部分而被存储起来。运作机理:当编译器实例化Fib<10>时,为了给其enumResult赋值,编译器需要对Fib<9>和Fib<8>进行实例化,同理,又需要针对Fib<7>和Fib<5、6>实例化同样的模板……,当实例化到Fib<1>和Fib<0>的时候,完全特化版被实例化,至此递归结束。这个处理过程类似于递归函数调用,编译器被用于解释元程序,生成的结果程序中仅包含一个常量值。导入范例//主模板templatestructIfThenElse{typedefT1ResultType;};//局部特化templatestructIfThenElse{typ6、edefT2ResultType;};//示例IfThenElse<(1+1==2),int,char>::ResultTypei;//i的类型为int2.类型选择基于给定的布尔常量表达式在两个类型之中二选一。若表达式为true,则T1被typedef为ResultT,否则ResultT代表T2。只针对模板参数的局部进行特化。主要思想利用模板特化机制实现编译期条件选择结构,利用递归模板实现编译期循环结构,模板元程序则由编译器在编译期解释执行。静态语言设施模板元编程使用静态C++语言成分,编程风格类似于函数式编程,其7、中不可以使用变量、赋值语句和迭代结构等。在模板元编程中,主要操作整型(包括布尔类型、字符类型、整数类型)常量和类型。被操纵的实体也称为元数据(Metadata)。所有元数据均可作为模板参数。其他元数据类型还包括枚举、函数指针/引用、全局对象的指针/引用以及指向成员的指针等。另外,已经有一些编译期浮点数计算探索(参见[注7])。由于在模板元编程中不可以使用变量,我们只能使用typedef名字和整型常量。它们分别采用一个类型和整数值进行初始化,之后不能再赋予新的类型或数值。如果需要新的类型或数值,必须引入新的typed8、ef名字或常量。静态语言设施编译期赋值通过整型常量初始化和typedef语句实现。例如:enum{Result=Fib::Result+Fib::Result};或staticconstintResult=Fib::Result+Fib::Result;成员类型则通过typedef引入,例如:typedefT1Resu
4、=1的情况处理N=0的情况特化必须放在主模板之后导入范例语句inti=Fib<10>::Result;被VC7.1编译成如下指令(IntelP4CPU):00411A1Emovdwordptr[i],37h字面量37h即为Fibonacci数列的第10项的值。可见,Fib<10>::Result的确被评估于编译期,结果作为处理器指令的一部分而被存储起来。运作机理:当编译器实例化Fib<10>时,为了给其enumResult赋值,编译器需要对Fib<9>和Fib<8>进行实例化,同理,又需要针对Fib<7>和Fib<
5、6>实例化同样的模板……,当实例化到Fib<1>和Fib<0>的时候,完全特化版被实例化,至此递归结束。这个处理过程类似于递归函数调用,编译器被用于解释元程序,生成的结果程序中仅包含一个常量值。导入范例//主模板templatestructIfThenElse{typedefT1ResultType;};//局部特化templatestructIfThenElse{typ
6、edefT2ResultType;};//示例IfThenElse<(1+1==2),int,char>::ResultTypei;//i的类型为int2.类型选择基于给定的布尔常量表达式在两个类型之中二选一。若表达式为true,则T1被typedef为ResultT,否则ResultT代表T2。只针对模板参数的局部进行特化。主要思想利用模板特化机制实现编译期条件选择结构,利用递归模板实现编译期循环结构,模板元程序则由编译器在编译期解释执行。静态语言设施模板元编程使用静态C++语言成分,编程风格类似于函数式编程,其
7、中不可以使用变量、赋值语句和迭代结构等。在模板元编程中,主要操作整型(包括布尔类型、字符类型、整数类型)常量和类型。被操纵的实体也称为元数据(Metadata)。所有元数据均可作为模板参数。其他元数据类型还包括枚举、函数指针/引用、全局对象的指针/引用以及指向成员的指针等。另外,已经有一些编译期浮点数计算探索(参见[注7])。由于在模板元编程中不可以使用变量,我们只能使用typedef名字和整型常量。它们分别采用一个类型和整数值进行初始化,之后不能再赋予新的类型或数值。如果需要新的类型或数值,必须引入新的typed
8、ef名字或常量。静态语言设施编译期赋值通过整型常量初始化和typedef语句实现。例如:enum{Result=Fib::Result+Fib::Result};或staticconstintResult=Fib::Result+Fib::Result;成员类型则通过typedef引入,例如:typedefT1Resu
此文档下载收益归作者所有