コンパイル時定数enum

2529 ワード

C++メタプログラミングを見ると、基本的に挙げられる例があります.
#include <iostream>
using namespace std;

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

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

int main()
{
   cout<<Factorial<5>::value<<endl; 
}

他のタイプでenumを置き換えることができるかどうか、static const intがenumの代わりになることに気づいた.
#include <iostream>
using namespace std;

template <int N>
struct Factorial 
{
    static const int value = N * Factorial<N - 1>::value;
};

template <>
struct Factorial<0> 
{
    static const int value = 1;
};

int main()
{
   cout<<Factorial<5>::value<<endl; 
}

上記の2つの例により、コンパイル中にvalueの値が計算されたため、実行中にvalueを直接出力できる構造が発見される.これもメタプログラミングの本質です.プログラムのコンパイル中にテンプレートを通じて新しいコードを生成し、その間にいくつかの操作を完了します.
Enumとstatic const intはコンパイル時定数ですが、enumとstatic const intの同じ点と違いは何ですか?
コードを見続けます:
#include <iostream>
using namespace std;

template <int N>
struct Factorial 
{
    enum  T{ value = N * Factorial<N - 1>::value };
	static const int value2 = N * Factorial<N - 1>::value2;
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
	static const int value2 = 1;
};

void test(const int &x)
{
  cout<<x<<endl;
}

int main()
{    
    test(Factorial<5>::value);
	test(Factorial<5>::value2); //undefined reference to `Factorial<4>::value2'
}

コードにvoid test(const int&x)を追加しました.
static const intテストを使用すると、undefined reference to`Factorial<4>::value 2'、Factorial<4>::value 2がコンパイル時に生成されなかったため、メタプログラミングが行われなかったとエラーが発生します.
具体的な原因は、googleを調べて、見識を広めました.
Static constant members are lvalues. So, if you have a declaration such as void test(const int &x) and you pass it the result of a meta-program test(Factorial<5>::value2); a compiler must pass the address of Factorial<5>::value2, which forces the compiler to instantiate and allocate the definition for the static member. As a result, the computation is no longer limited to a pure “compile-time” effect. Enumeration values aren’t lvalues (that is, they don’t have an address). So, when you pass them “by reference,” no static memory is used. It’s almost exactly as if you passed the computed value as a literal. These considerations motivate us to use enumeration values in all meta-programs.