利用编译器递归的模板算阶乘的代码如下,希望编译期就求值完毕,也就是说比如这么写 int res = factorial< 3 >::result; 就相当于写int res = 6;
template< unsigned int num >
struct factorial
{
enum
{
result = ( num == 0 )? 1 : num * factorial< num - 1 >::result
};
};
上面的代码看起来不错,但是无法通过编译(VC.NET 2003),会报一个C1202: 递归类型或函数依赖项上下文太复杂。
想要编过就得再带一个特化版的factorial:
template<>
struct factorial< 0 >
{
enum
{
result = 1
};
};
这样写的话原来的定义就可以简化为 result = num * factorial< num - 1 >::result了
仔细看原来的代码,递归明明是可以中止的啊?但是仔细一想,不能要求编译器那么聪明,它不可能编译到
num == 0的时候一看哈哈发现能中止(如果不能中止就停不下来了),应该是直接一看是递归,然后再一看没有特化版,就直接报错了(我猜的)。
试了一下,具现 factorial< num >的地方不管num给多大,编译器都是立即报出错误,可见一定是在真正开始递归之前就已经下结论了
这样的缺点是只要用到模板递归,就一定要带一个特化版,心里总有些不爽。当然有些人会觉得这样看起来比较清楚,各有所好吧