2012-02-01 60 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,否)。