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

后端 未结 3 911
刺人心
刺人心 2021-02-05 10:47

I want to create a structure that allocates statically an array of 2^N bytes, but I don\'t want the users of this structure to specify this size as the exponent

3条回答
  •  悲&欢浪女
    2021-02-05 11:40

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

    #include
    // #include 
    
    template
    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
    make_power_of_two
    {
        enum { val = 1 << N };
    };
    
    my_stupid_array::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);
    }
    

提交回复
热议问题