TMP的阶乘运算

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


 

你可能感兴趣的:(TMP的阶乘运算)