4

constexpr static int constさて、コンパイル時に一連の配列を初期化することで、何か賢いことをしようとしていました。これらの配列を初期化することによって実行時のパフォーマンスがまったく管理されていないにもかかわらず、それは楽しい小さな演習のように思えました。それが可能かどうかを確認するためにテストセットアップを作成しましたが、最終的にこれを実行できるようになりました。

struct Test
{
    constexpr static int const array[10] = Array<int, 10, 0, Increment>::array;
};

constexpr int const Test::array[10];

int main()
{
    cout << Test::array[3] << '\n';
}

ここでは、0 から始まる10 個の s を含むArrayと呼ばれる静的メンバーがあり、後続の各要素の値は、 (つまり)と呼ばれるテンプレート メタプログラミング ファンクターによって決定されます。予想どおり、プログラムは数字を出力します。arrayintIncrement{0, 1, ..., 9}3

すごいですよね?今はファンクタを書くだけで、コンパイル時にあらゆる種類のファンキーなパターンで配列を初期化できます。Test次のステップ: 次のようにクラス テンプレートを作成して、配列サイズ 10 のハードコードを解除します。

template <size_t Size>
struct Test
{
    constexpr static int const array[Size] = Array<int, Size, 0, Increment>::array;
};

template <size_t Size>
constexpr int const Test<Size>::array[Size];

int main()
{
    cout << Test<10>::array[3] << '\n';
}

ただし、突然、次のメッセージでコンパイルされなくなりました。

test.cc:43:72: error: array must be initialized with a brace-enclosed initializer

なぜこれが起こるのですか?クラスをクラステンプレートにすると、この種の初期化が無効になる理由はありますか、または GCC で実装されていない/バグのあるものに遭遇しましたか?

Array参考までに、リクエストに応じて残りのコード (たとえばの実装) を投稿できます。今のところ、これで十分だと思います。

編集Arrayここでスペースを節約するために、別の簡単な実装でエラーを再現できます。

template <size_t Size>
struct Array
{
    constexpr static int const array[Size] = {};
};

template <size_t Size>
struct Test
{
    constexpr static int const array[Size] = Array<Size>::array;
};
4

1 に答える 1