(摘自effective C++)
之前使用模板时,只记得有typename,class做参数的。当再看到时,才感觉还是挺神奇。
模板参数并不局限于类型,可以使用编译器内置类型。
template告诉编译器,虽有的定义中将包含一个或多个未确定的量(常量或类型),当该模板产生实际代码时,必须制定这些量由编译器来替换。
TMP 的 "hello world" 程序在编译期间计算一个阶乘。它不是一个很令人兴奋的程序,不过,即使不是 "hello world",也有助于语言入门。TMP 阶乘计算示范了通过 recursive template instantiation(递归模板实例化)实现循环。它也示范了在 TMP 中创建和使用变量的一种方法。看:
template<unsigned n> // general case: the value of
struct Factorial // Factorial<n> is n times the value
{ // of Factorial<n-1>
enum { value = n * Factorial<n-1>::value };
};
template<> // special case: the value of
struct Factorial<0> { // Factorial<0> is 1
enum { value = 1 };
};
给出这个 template metaprogram(模板元程序)(实际上只是单独的 template metafunction(模板元函数)Factorial),你可以通过引用 Factorial<n>::value 得到 factorial(n) 的值。
代码的循环部分出现在 template instantiation(模板实例化)Factorial<n> 引用了 template instantiation(模板实例化)Factorial<n-1> ,这样子它便会不断实例出新的类型Factorial<n-1>,并取得各个类型中value值来相乘,由于是enum常量,所以每个value的值都会在编译时计算出来。
所有正确的 recursion(递归)都会有一个出口。这里,它就是 template specialization(模板特化)Factorial<0>。
Factorial template 的每一个 instantiation(实例)都是一个 struct,而每一个 struct 都会有相应的阶乘值值value。
编译期检测数值是否相等
template<int m, int n>
struct CheckEqualInCompileTime
{
enum { var = (m == n) ? 0 : -1, };
char check[var];
};
CheckEqualInCompileTime<sizeof(A) / sizeof(int), ENUM_MAX + 1> checka;