1

次のテンプレート定義とテンプレート特殊化定義がどのように機能するかを理解するのが難しいですか? 私には、factorial<34>またはfactorial<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
4

2 に答える 2

6

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

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

1 の階乗は 1 だということです。

もう 1 つのテンプレートは、数値の階乗はその数値に階乗から 1 を引いたものであると単純に述べています。

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

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

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

于 2012-02-01T15:04:36.033 に答える
5

それは実際には質問ではなく、声明です。テンプレート引数は型である必要はありません、ほとんどの場合は型であるため、型以外のテンプレート引数を見たことがないかもしれません。

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

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

于 2012-02-01T15:09:02.743 に答える