C 模板元编程技术研究
2008-02-23 05:24:47来源:互联网 阅读 ()
1994年,C 标准委员会在圣迭哥举行的一次会议期间Erwin Unruh展示了一段能够产生质数的代码。这段代码的特别之处在于质数产生于编译期而非运行期,在编译器产生的一系列错误信息中间夹杂着从2到某个设定值之间的任何质数:
// Prime number computation by Erwin Unruh template <int i> struct D { D(void*); operator int(); }; template <int p, int i> struct is_prime { enum { prim = (p%i) && is_prime<(i > 2 ? p : 0), i -1> :: prim }; }; template < int i > struct Prime_print { Prime_print<i-1> a; enum { prim = is_prime<i, i-1>::prim }; void f() { D<i> d = prim; } }; struct is_prime<0,0> { enum {prim=1}; }; struct is_prime<0,1> { enum {prim=1}; }; struct Prime_print<2> { enum {prim = 1}; void f() { D<2> d = prim; } }; #ifndef LAST #define LAST 10 #endif main () { Prime_print<LAST> a; } |
类模板D只有一个参数为void*的构造器,而只有0才能被合法转换为void*。1994年,Erwin Unruh采用Metaware 编译器编译出错信息如下(连同其他一些信息,简短起见,他们被删除了):
| Type `enum{}′ can′t be converted to txpe `D<2>′ ("primes.cpp",L2/C25). | Type `enum{}′ can′t be converted to txpe `D<3>′ ("primes.cpp",L2/C25). | Type `enum{}′ can′t be converted to txpe `D<5>′ ("primes.cpp",L2/C25). | Type `enum{}′ can′t be converted to txpe `D<7>′ ("primes.cpp",L2/C25). |
如今,上面的代码已不再是合法的C 程式了。以下是Erwin Unruh亲手给出的修订版,能够在今天符合标准的C 编译器上进行编译:
// Prime number computation by Erwin Unruh template <int i> struct D { D(void*); operator int(); }; template <int p, int i> struct is_prime { enum { prim = (p==2) || (p%i) && is_prime<(i>2?p:0), i-1> :: prim }; }; template <int i> struct Prime_print { Prime_print<i-1> a; enum { prim = is_prime<i, i-1>::prim }; void f() { D<i> d = prim ? 1 : 0; a.f();} }; template<> struct is_prime<0,0> { enum {prim=1}; }; template<> struct is_prime<0,1> { enum {prim=1}; }; template<> struct Prime_print<1> { enum {prim=0}; void f() { D<1> d = prim ? 1 : 0; }; }; #ifndef LAST #define LAST 18 #endif main() { Prime_print<LAST> a; a.f(); } |
在GNU C (MinGW Special) 3.2中编译这段程式时,编译器将会给出如下出错信息(连同其他一些信息,简短起见,他们被删除了):
Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 17]' Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 13]' Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 11]' Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 7]' Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 5]' Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 3]' Unruh.cpp:12: initializing argument 1 of `D<i>::D(void*) [with int i = 2]' |
这个例子展示了能够利用模板实例化机制于编译期执行一些计算。这种通过模板实例化而执行的特别的编译期计算技术即被称为模板元编程。
顺便说一句,因为编译器的出错信息并未被标准化,所以,假如您在Visual C 、Borland C 等编译器上看不到这么周详的出错信息,请不必讶异。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇: 关于C 异常处理的心得体会
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash