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;
}