How do I check if a template parameter is a power of two?

旧巷老猫 提交于 2019-12-03 01:54:07

These days, with constexpr and the bit twiddling hacks you can just

constexpr bool is_powerof2(int v) {
    return v && ((v & (v - 1)) == 0);
}

static_assert to the rescue (C++11 only, uncomment BOOST_STATIC_ASSERT for C++03):

#include<iostream>
// #include <boost/static_assert.hpp>

template<int N>
struct is_power_of_two {
    enum {val = N && !(N & (N - 1))};
    static_assert(val, "should use a power of 2 as template parameter");
    // BOOST_STATIC_ASSERT(val); // without C++11 support, won't take a string message
};

int main()
{
        std::cout << is_power_of_two<2>::val << "\n";
        std::cout << is_power_of_two<3>::val << "\n";
}

Ideone output for C++11

Ideone output for C++03

UPDATE1: other idea (I know you don't want this, but it is a lot easier for large exponents):

template<int N>
make_power_of_two
{
    enum { val = 1 << N };
};

my_stupid_array<char, make_power_of_two<5>::val > a1; // size 2^5 = 32

UPDATE2: based on comments by @sehe in the chat, you can do this for constexpr functions as well

constexpr bool is_power_of_two(int x)
{
    return x && ((x & (x-1)) == 0);
}

You can use static_assert to provide an error message:

template<int N>
struct is_power_of_two {
    static_assert((N > 1) & !(N & (N - 1)), "Template parameter must be a power of two.");
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!