17

2^N バイトの配列を静的に割り当てる構造を作成したいのですが、この構造のユーザーにこのサイズを指数として指定してほしくないのです。例:

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

このテンプレート パラメータが 2 のべき乗であるかどうかを確認し、これについて適切なメッセージでユーザー警告するにはどうすればよいですか?

簡単なテンプレートでこれを確認できました。

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

ただし、これについてユーザーに適切なメッセージで警告することはできません。何か案は?

編集

あいまいな例を修正しました。

編集

1 は確かに 2 のべき乗です。それを修正しました!:)

編集

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

編集

わかりました。これは、アサートが失敗したときに受け取るはずのメッセージでした。しかし、それではユーザーにまともなメッセージを伝えることができません。:(

4

3 に答える 3

23

最近ではconstexpr少しいじるハックを使って、

constexpr bool is_powerof2(int v) {
    return v && ((v & (v - 1)) == 0);
}
于 2013-10-16T09:16:37.310 に答える
22

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";
}

C++11のIdeone出力

C++03のIdeone出力

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);
}
于 2012-05-14T14:40:52.623 に答える
11

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.");
};
于 2012-05-14T14:41:24.917 に答える