TMP的阶乘运算示范如何通过"递归模板实例化"(recursive template instantiation)实现循环,以及如何在TMP中创建和使用变量:
template<unsigned n> //一般情况下:Factorial<n>的值是 struct Factorial // n乘以Factorial<n-1>的值 { enum{ value=n * Factorial<n-1>::value }; }; template<> //特殊情况下: struct Factorial<0> //Factorial<0>的值是1 { enum{ value=1 }; };
有了这个template metaprogram(其实只是个单一的template metafunction Factorial),只要你引用Factorial<n>::value就可以得到n阶乘值。
循环发生在template实例体Factorial<n>内部引用另一个template实例体Factorial<n-1>之时。和所有良好递归一样,我们需要一个特殊情况造成递归结束。这里的特殊情况是template特化体Factorial<0>。
每个Factorial template实例体都是一个struct,每个struct都使用enum hack(见条款2)声明一个名为value的TMP变量,value用来保存当前计算所得的阶乘值。如果TMP拥有真正的循环构件,value应当在每次循环体内获得更新。但由于TMP系以“递归模板实例化”(recursive template instantiation)取代循环,每个实例体有自己的一份value,而每个value有其循环体内的适当值。
你可以这样使用Factorial:
int main() { std::cout<<Factorial<5>::value; //印出120 std::cout<<Factorial<10>::value; //印出 3628800 }
再举个例子:
#include <iostream> using namespace std; template<typename T> struct is_non_template_param { enum { have_template_param =1 }; }; template<> struct is_non_template_param<void> { enum { have_template_param =0 }; }; template<typename T1,typename T2,typename T3,typename T4,typename T5> struct template_params { enum { count = is_non_template_param<T1>::have_template_param + is_non_template_param<T2>::have_template_param + is_non_template_param<T3>::have_template_param + is_non_template_param<T4>::have_template_param + is_non_template_param<T5>::have_template_param }; }; template<typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void> struct Delegate { enum{ ParamsCount = template_params<T1,T2,T3,T4,T5>::count }; int GetParamsCount() { return ParamsCount; } }; int main() { Delegate<int,double,char> d1; Delegate<int,int*,char*,int> d2; Delegate<void> d3; cout<<"d1 params count =" << d1.GetParamsCount()<<endl; cout<<"d2 params count =" << d2.GetParamsCount()<<endl; cout<<"d3 params count =" << d3.GetParamsCount()<<endl; return 0; }