Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive template metaprogramming

Tags:

c++

templates

For calculating factorial I can use :

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

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

and then can use it like following

x=factorial<8>::value;

So, is it possible to get similar recursive template for

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

I can think of this:

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

But don't know how to set a base case.

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

Any ideas ?

like image 500
P0W Avatar asked Aug 14 '13 13:08

P0W


1 Answers

You could use partial specialization

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

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

In C++11, instead of creating a template, you could turn the function to constexpr instead.

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.
like image 198
kennytm Avatar answered Sep 28 '22 08:09

kennytm