3

コンパイル時の定数サイズ(のような)でデータ構造を実装したいstd::array。このデータ構造を次のように初期化できるようにしたい:

MyStruct<3, int> example = {1, 2, 3};

これは、コンストラクター like: を使用して正常に動作しますが、コンパイル時に両方が既知であってもMyStruct(std::initializer_list<T> elements)、コンパイラーは内部構造体とに同じサイズを適用しません。elements

はコンパイル時定数ではないstatic_assertので使えません。elements.size()

elementsと同じサイズをコンパイル時に強制する方法はありますMyStructか?

4

2 に答える 2

2

可変個引数テンプレートを使用してコンストラクターを試すことができます。

template<std::size_t N, typename E>
struct MyStruct {
    int otherStuff;
    E values[N];

    template<typename ...TT>
    MyStruct(TT&&...t) : values{std::forward<TT>(t)...} {
        static_assert(N == sizeof...(t), "Size mismatch!");
        for (size_t i = 0; i < N; i++) std::cout << values[i] << ",";
        std::cout << std::endl;
    }
};

これは、次の場合に期待どおりに機能します。

MyStruct<3, int> example = {1,2,3};
MyStruct<3, int> exampleFail = {1,2}; //error: static assertion failed: Size mismatch!

リストの初期化に関しては、 と の間std:arrayにはまだ違いがあることに注意してください。MyStruct

MyStruct<3, int> exampleList{1,2,3}; // works
std::array<int, 3> arr = {1,2,3};    // works, but warning with clang++
std::array<int, 3> arrList{1,2,3};   // works with g++, does not compile with clang++

その理由は、公式の欠陥レポートで文書化されているように、ブレースの省略が常に適用されるとは限らないため、単一のブレースは std::array に対してのみ機能するためです。

于 2013-07-31T14:20:47.437 に答える