2013-08-14 9 views
5

再帰テンプレートメタプログラミング

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

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

、その後だから、

x=factorial<8>::value;

を次のようにそれを使用することができ、それは

のために同様の再帰的なテンプレートを取得することが可能です
unsigned Log2(unsigned n, unsigned p = 0) { 
    return (n <= 1) ? p : Log2(n/2, p + 1); 
} 

私はこれを考えることができます:

template<int N,unsigned int P=0> struct Log2 
    { enum { value = Log2<N/2,P+1>::value }; }; 

しかし、ベースケースの設定方法はわかりません。

template<> struct Log2<0,???> { enum { value = ???? }; }; 

答えて

8

かわりに、テンプレートを作成する、あなたの代わりにconstexprに関数を回すことができる、C++ 11では

template <unsigned p> 
struct Log2<0, p> { enum { value = p }; }; 

template <unsigned p> 
struct Log2<1, p> { enum { value = p }; }; 

部分特殊化を使用することができます。

constexpr unsigned Log2(unsigned n, unsigned p = 0) { 
    return (n <= 1) ? p : Log2(n/2, p + 1); 
} 

std::array<int, Log2(256)> x {{1, 2, 3, 4, 5, 6, 7, 8}}; 
//    ^^^^^^^^^ Just a compile-time function call. 
+0

私はそれが 'value = p-1'であるべきだと思いますか? – P0W

+0

@ P0W:ちょうど 'n <= 1'のときに' p'を返す実装を使っています。 – kennytm

+0

ええ、ありがとう – P0W