私はからの例を使用しました
http://en.wikipedia.org/wiki/Template_metaprogramming
const unsigned long long y = Factorial<0>::value; // == 1
コンパイラーが型チェックを実行できることは理解していますが、型があるべき場所に0を入れることができ、それが値として使用されるとは思いませんでした。
誰かがこれがどのように機能しているか説明できますか?
ありがとう
私はからの例を使用しました
http://en.wikipedia.org/wiki/Template_metaprogramming
const unsigned long long y = Factorial<0>::value; // == 1
コンパイラーが型チェックを実行できることは理解していますが、型があるべき場所に0を入れることができ、それが値として使用されるとは思いませんでした。
誰かがこれがどのように機能しているか説明できますか?
ありがとう
タイプがあるべき場所に0を入れることができるとは思いませんでした、そしてそれは値として取られるでしょう
問題は仮定です:それは「タイプがどこにあるべきか」ではありません。むしろ、「テンプレート引数を指定できる場所」です。
この場合、型以外のテンプレート引数があります。
これは、型テンプレート引数とは異なる機能であるという理由だけで機能します。
まさにその通りです。C ++テンプレートの基本について読むために、C ++テンプレート:完全ガイドまたはそのリストにある他の多くの本をお勧めします。
その特定の例では:
template <int N>
struct Factorial {
enum { value = N * Factorial<N - 1>::value };
};
template <>
struct Factorial<0> {
enum { value = 1 };
};
コンパイラはクラスを再帰的に生成します。テンプレート自体はクラスではなく、クラスが生成された後の一連のルールにすぎないことを忘れないでください。
最初は、Factorial<0>
存在するだけです。次に、次のように記述します。
const int x = Factorial<4>::value;
Factorial<4>
これは、次のように変換されるクラスを生成する必要があることを示しています。
template <>
struct Factorial<4> {
enum { value = 4 * Factorial<3>::value };
};
これもクラスを生成するように指示Factorial<3>
します。Factorial<0>
これは、すでに定義されており、value
メンバーを計算するために新しいクラスを生成する必要がないため、到達すると停止します。
基本的に、計算を実行時からコンパイル時に移動します。これが常に機能するとは限らないことに注意してください(の値によってはN
、コンパイラがそれほど多くのレベルのテンプレート再帰をサポートしていない場合があります)。また、これによりコードサイズが大きくなります。
これは方法のためです-これが機能する理由は、標準で許可されているためです。