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();} };
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]' 这个例子展示了可以利用模板实例化机制于编译期执行一些计算。这种通过模板实例化而执行的非凡的编译期计算技术即被称为模板元编程。
template <typename T> inline T sum_array(int Dim, T* a) { T result = T(); for (int i = 0; i < Dim; ++i) { result += a[i]; } return result; } 这当然可行,但我们也可以利用模板元编程技术来解开循环:
// sumarray2.h
// 原始模板 template <int Dim, typename T> class Sumarray { public: static T result(T* a) { return a[0] + Sumarray<Dim-1, T>::result(a+1); } };
// 作为终结准则的局部特化版 template <typename T> class Sumarray<1, T> { public: static T result(T* a) { return a[0]; } }; 用法如下: