2012-02-01 6 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

+2

人は*タイプ*のパラメータだけを持つテンプレートを使ってテンプレートに導入されるかもしれません。私はそれが、新しいもので奇妙な価値観の考え方だと思う。 –

+0

何が問題なのですか? –

答えて

6

これはテンプレートメタプログラミングの例です。このプログラムは、再帰を使用してコンパイル時に階乗を計算します。再帰のベースはここにある:

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

これは、他のテンプレートは、単純に数値の階乗はその数倍階乗でマイナス1

template<int T> 
struct factorial { 
    enum { value = factorial<T - 1>::value * T }; 
}; 
と言う1の階乗は1

であることを述べています

古典的な意味では実際には「呼び出し」がないので、テンプレートは、コンパイル時に計算されたT-1に等しいテンプレート引数を使用して、自体をインスタンス化します。

P.S.警告は、階乗が32ビット整数をオーバーフローすることを示しています。

+0

'int'は32ビットと仮定します。それは重要ではない。計算は64ビット整数もオーバーフローします。 –

+2

@DonalFellows: 'int'は32ビットなので、ここは13です!それはオーバーフローする。 –

5

これは本当に問題ではありませんが、それは声明です。テンプレートの引数はにはの型はありませんが、はほとんどの場合、型がであるため、前に非型テンプレートの引数を見たことがないかもしれません。前記

factorial<1>は> 1 factorial<N-1>を指す一般的なケースを使用して(value=1で)特殊を使用し、Nとfactorial<N>。これにより、(テンプレートが再帰的に展開されるため)階乗のコンパイル時の評価が得られます。

しかし、34の階乗はどれくらい大きいのですか?整数に収まると思いますか? (回答:295232799039604140847618609643520000000、いいえ)。

関連する問題