(摘自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;