C++模板元编程 导言

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++等编译器上看不到这么详细的出错信息,请不必讶异。
原文出自【比特网】,转载请保留原文链接:http://bbs.chinabyte.com/thread-373493-1-1.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值