如何检查是否一个模板参数是二的幂?(How do I check if a template par

2019-07-29 09:01发布

我想创建静态分配的2 ^ N字节的数组的结构,但我不希望这样结构的用户指定这个尺寸指数。 例:

my_stupid_array<char, 32> a1; // I want this!
my_stupid_array<char, 5> a2; // And not this...

如何检查,如果这个模板参数是二的幂用这个一个不错的消息,警告用户?

我已经能够用简单的模板来检查这一点:

template<int N>
struct is_power_of_two {
    enum {val = (N >= 1) & !(N & (N - 1))};
};

然而,我无法警告该用户提供了一个健全的消息。 有任何想法吗?

编辑

修正了模棱两可的例子。

编辑

1是两个确实是一个动力。 修正了! :)

编辑

使用BOOST_STATIC_ASSERT,我得到这个编译错误此代码与GCC:

template<int N>
struct is_power_of_two {
    enum {val = (N >= 1) & !(N & (N - 1))};
    BOOST_STATIC_ASSERT(val);
};

错误

..\main.cpp:29:1: error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>' 

http://ideone.com/cMfEf

编辑

哦,我明白了。 这是我应该得到时断言失败的消息。 但是,这无法给用户一些理智的消息。 :(

Answer 1:

这些天, constexpr和位摆弄黑客可以只

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


Answer 2:

static_assert救援(仅C ++ 11,用于C ++ 03取消注释BOOST_STATIC_ASSERT):

#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输出为C ++ 11

Ideone输出用于C ++ 03

UPDATE1:其他的想法(我知道你不希望这样,但它是一个更容易为大指数):

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:基于在聊天@sehe评论,你可以做到这一点的constexpr功能以及

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


Answer 3:

您可以使用static_assert提供一个错误信息:

template<int N>
struct is_power_of_two {
    static_assert((N > 1) & !(N & (N - 1)), "Template parameter must be a power of two.");
};


文章来源: How do I check if a template parameter is a power of two?