2011-07-08 9 views
8

せずに私はコンパイル時に階乗を計算します。私はこの問題を解決する方法を見つけましたが、enumを使用せずにこの問題の解決方法があるかどうかを知りたいと思います。ここでは、enumを使用するソリューションです。は、コンパイル時に数の階乗を計算することが可能ですが、列挙型

#include <iostream> 
template <int n> 
struct fact 
{ 
    enum{value = n*fact<n-1>::value}; 
}; 

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

int main() 
{ 
    std::cout << fact<10>::value; 
} 

他に解決策がない場合は、enumが必須である理由を説明してください。彼らはコンパイル時に解決されると仮定しているため

置き換え
+0

http://en.wikipedia.org/wiki/Template_metaprogramming、それは[サンプル](httpです。 org/wiki/Template_metaprogramming#Compile-time_class_generation) – sehe

答えて

10

は、それはそのように書かれているより多くのコンパイラはその列挙スタイルの表記を受け入れるため。この言語は、インライン初期化を持つconst integral-typeクラスメンバをサポートしていますが、一部のコンパイラはその点で標準に準拠していません。うまく、この点では、次の作品に準拠しているコンパイラで://en.wikipedia:

#include <iostream> 
template <unsigned int n> 
struct fact 
{ 
    static const unsigned int value = n*fact<n-1>::value; 
}; 

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

int main() 
{ 
    std::cout << fact<10>::value << "\n"; 
} 
+0

ファクト<0>はおそらくベースケース(0!= 1) –

+0

でなければなりません。同じ解決策はhttp://en.wikipedia.org/wiki/Template_metaprogramming – sehe

+0

にあります。ウィキペディアの記事のソリューションはenumバージョンを使用しています。列挙型の使用は必須ではありません。 –

7

、と

enum{value}; 

static int const value; // or unsigned int 

enum sが必須です。あなたが計算した結果がコンパイル時に行われていなければならないことを保証します。そのような他のタイプは、static int const(任意の整数タイプを意味する)である。

は説明するために:

enum E { 
X = strlen(s); // is an error, because X is a compile time constant 
}; 
+0

ここで列挙型は必須ではありません。この言語では、整数型の静的constメンバーに初期値を与えることができます。列挙型は、準拠していないコンパイラ(明らかに非常に豊富です)でのみ必要です。 –

+0

@iammilindは答えに感謝します。 'static int'がなぜ受け入れられないのか、' static int const'を書く必要がある理由を知りたいです。 –

+0

@Samvel、 'static int'はコンパイル時に解決されないためです。たとえあなたがそれをしても。コンパイル時定数が必要です。 – iammilind

7

を別の方法として、あなたは、静的定数メンバを使用することができます。代わりの表記がありますが

template <unsigned int n> 
struct fact { static const unsigned int value = n * fact<n-1>::value; } 
関連する問題