- 元编程
- 23.2反思元编程的维度
- 23.3递归实例化的代价
- 23.4计算完整性
- 23.5递归实例化与递归模板实参
- 23.6枚举值与静态常量
- 23.7 Afternotes
23.7 Afternotes
最早记录的元程序示例是由Erwin Unruh编写的,当时他在c++标准化委员会中代表西门子。他注意到模板实例化过程的计算完整性,并通过开发第一个元程序来证明他的观点。他使用了Metaware编译器,并诱使它发出包含连续素数的错误消息。以下是1994年c++委员会会议上流传的代码(经过修改,现在可以在符合标准的编译器上编译):6
元/ unruh.cpp
//质数计算
//(修改自1994年欧文·昂鲁的原文)
模板
Struct is_prime {
enum {pri = (p = = 2) | | ((p % i) & & is_prime < (> 2 ? p: 0),张>::pri)};
};
模板< >
Struct is_prime<0,0> {
enum {pri = 1};
};
模板< >
Struct is_prime<0,1> {
enum {pri = 1};
};
模板< int我>
结构D {
D (void *);
};
模板< int我>
CondNull {
Static int const value = i;
};
模板< >
struct CondNull<0> {
静态void* value;
};
void* CondNull<0>::value = 0;
模板< int我>
struct Prime_print {//主模板for循环打印素数
张Prime_print < >;
Enum {pri = is_prime::pri};
无效f() {
D D = CondNull::value;// 1为错误,0为新
a.f ();
}
};
模板< >
struct Prime_print<1> {//完全专门化结束循环
enum {pri = 0};
无效f() {
D<1> D = 0;
};
};
的ifndef去年
#define LAST 18
# endif
int main ()
{
Prime_print去年> <;
a.f ();
}
如果编译这个程序,编译器将在,时打印错误消息Prime_print: f ()的初始化d失败。当初始值是1因为只有一个构造函数void *,只有0有有效的转换到void *.例如,在一个编译器上,我们得到(在其他几个消息中)以下错误:7
unruh.cpp:39:14:错误:没有可行的从' const int '到' D<17> '的转换
unruh.cpp:39:14:错误:没有可行的从' const int '到' D<13> '的转换
unruh.cpp:39:14:错误:没有可行的从' const int '到' D<11> '的转换
unruh.cpp:39:14:错误:没有可行的从' const int '到' D<7> '的转换
unruh.cpp:39:14:错误:没有可行的从' const int '到' D<5> '的转换
unruh.cpp:39:14:错误:没有可行的从' const int '到' D<3> '的转换
unruh.cpp:39:14:错误:没有可行的从' const int '到' D<2> '的转换
c++模板元编程作为一种严肃的编程工具的概念最初是由Todd Veldhuizen在他的论文中流行起来的(并且在某种程度上形式化了)使用c++模板元程序(见[VeldhuizenMeta95])。Todd关于Blitz++的工作(一个c++的数值数组库,参见[闪电战+ +])还介绍了元编程的许多改进和扩展(以及27章介绍的表达式模板技术)。
本书的第一版和Andrei Alexandrescu的“现代c++设计”(参见[AlexandrescuDesign])通过编目一些至今仍在使用的基本技术,促成了利用基于模板的元编程的c++库的爆炸式增长。Boost项目(参见[提高[]在给这次爆炸带来秩序方面起了重要作用。早期,它引入了MPL(元编程库),它定义了一个一致的框架类型元编程通过Abrahams和Gurtovoy的著作《c++模板元编程》(参见[Boost-MPL])。
Louis Dionne在使元编程在语法上更易于访问方面取得了其他重要进展,特别是通过他的Boost。Hana库(参见[BoostHana])。Louis和Andrew Sutton、Herb Sutter、David Vandevoorde等人现在正在标准化委员会中带头努力,为该语言中的元编程提供一流的支持。这项工作的一个重要基础是探索应该通过反射获得哪些程序属性;Matúš Chochlík、Axel Naumann和David Sankel是该领域的主要贡献者。
在[BartonNackmanJohn J. Barton和Lee R. Nackman说明了在执行计算时如何跟踪维度单位。的SIunits图书馆是一个更全面的处理物理单位的图书馆,由沃尔特·布朗([BrownSIunits])。的std::空间组件,我们将其用作第534页第23.1.4节的灵感,它只处理时间和日期,由Howard Hinnant贡献。