2012-02-01 30 views
1

我难以理解以下模板定义和模板专业化定义是如何工作的?对我来说,factorial<34>factorial<T-1>看起来很奇怪!因子<T - 1>在模板定义中的含义

例如:

factorial<T - 1>::value 

意味着什么?

#include <iostream> 

template<int T> 
struct factorial { 
    enum { value = factorial<T - 1>::value * T }; 
}; 

template<> 
struct factorial<1> { 
    enum { value = 1 }; 
}; 

int main() 
{ 
    std::cout << factorial<34>::value << std::endl; 

}  

g++ -o testSTL01 testSTL01.cpp -Wall 
testSTL01.cpp: In instantiation of ‘factorial<13>’: 
testSTL01.cpp:5:3: instantiated from ‘factorial<14>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<15>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<16>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<17>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<18>’ 
testSTL01.cpp:5:3: [ skipping 11 instantiation contexts ] 
testSTL01.cpp:5:3: instantiated from ‘factorial<30>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<31>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<32>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<33>’ 
testSTL01.cpp:5:3: instantiated from ‘factorial<34>’ 
testSTL01.cpp:15:29: instantiated from here 
testSTL01.cpp:5:3: warning: integer overflow in expression 
start to run the app ... 

0 
+0

它看起来很简单。你不明白哪部分? – Mankarse 2012-02-01 15:03:10

+2

也许这是因为人们通过仅具有* type *参数的模板被引入到模板中。我认为这只是价值参数的想法,对某些人来说是新奇而陌生的。 – 2012-02-01 15:04:56

+0

这是什么问题? – 2012-02-01 15:05:02

回答

6

这是一个模板元编程的例子。该程序使用递归在编译时计算阶乘。递归的基础是在这里:

template<> 
struct factorial<1> { 
    enum { value = 1 }; 
}; 

它说的1阶乘是1

中其他的模板简单地说,一些阶乘是次数阶乘减1

template<int T> 
struct factorial { 
    enum { value = factorial<T - 1>::value * T }; 
}; 

由于在经典意义上确实没有“呼叫”,因此模板实例化了本身,其模板参数等于编译时计算的T-1

P.S.该警告显示34的阶乘溢出32位整数。

+0

你认为'int'是32位。并不重要;该计算也会溢出一个64位整数。 – 2012-02-01 15:10:24

+2

@DonalFellows:'int'在这里是32位,因为它是13!溢出。 – 2012-02-01 15:16:47

5

这不是一个真正的问题,而是一个声明。模板参数不是是类型,但在绝大多数情况下,它们是都是类型,所以您可能以前没有看到非类型的模板参数。

也就是说,factorial<1>使用专业化(与value=1)和factorial<N>与N> 1使用一般情况下,这是指factorial<N-1>。这为您提供了阶乘的编译时评估(因为模板递归地扩展)。

但是你有什么想法34的阶乘有多大?你会期望适合一个整数? (答案:295232799039604140847618609643520000000,否)。