If you really need to do this, create your own log2, which works at compile time and passes it to the bitter template argument.
constexpr unsigned Log2(unsigned n, unsigned p = 0) {
return (n <= 1) ? p : Log2(n / 2, p + 1);
}
constexpr size_t bitCount = Log2(X);
std::bitset<bitCount> bits;
Living example .
Here's a solution using template metaprograms, i.e. without use constexpr:
template<int N,unsigned int P=0>
struct Log2 { enum { value = Log2<N/2,P+1>::value }; };
template <unsigned p>
struct Log2<0, p> { enum { value = p }; };
template <unsigned p>
struct Log2<1, p> { enum { value = p }; };
std::bitset<Log2<4>::value> bits;
Living example .
This version should work both in C ++ 03 and C ++ 11; however, if you have access to C ++ 11, I would still recommend the path constexpras it was cleaner (easier to understand).