7

次のコードは、-std=c++11 を使用すると、gcc 4.9.1 および clang-3.6 でコンパイルおよび実行されます。

struct Bar
{
    int x;
};

struct Foo
{
    static constexpr Bar bars[] = {1, 2, 3};
};

constexpr Bar Foo::bars[];

ただし、gcc 4.8.3 では失敗し、エラー メッセージが表示されます。

./cpptest.cpp:14:43: error: could not convert '1' from 'int' to 'const Bar'
     static constexpr Bar bars[] = {1, 2, 3};
                                           ^
./cpptest.cpp:14:43: error: could not convert '2' from 'int' to 'const Bar'
./cpptest.cpp:14:43: error: could not convert '3' from 'int' to 'const Bar'

ちなみに、同じことをしbarsて static const グローバル配列を作成すると、gcc 4.8 と clang で正常にコンパイルされます。リスト内の各整数リテラルを追加の のペアで囲むと、問題なくコンパイルされます{}

これは gcc 4.8 のバグですか? 標準は、これに適した構文は何だと言っていますか? 余分な中括弧を省略した場合、C++11 統一初期化標準のどの部分が呼び出されますか?

編集:標準では、これにより集約の初期化が呼び出され、「ブレースの省略」が可能になると規定されているようです。したがって、gcc 4.9 で修正された gcc 4.8 のバグのようですが、標準を読む自信がまったくありません。また、これに関する gcc のバグ トラッカーでバグ レポートが見つからないように見えるので、簡単に間違っている可能性があります。

4

1 に答える 1

2

やりたいことを実行するには、Foo 内で constexpr コンストラクターを指定する必要があります。

struct Bar
{
    constexpr Bar(int c) : x(c)
    {}

    int x;
};

struct Foo
{
    static constexpr Bar bars[] = {1, 2, 3};
};

constexpr Bar Foo::bars[];

どうやら gcc 4.8.3 は中括弧内の値を Bar オブジェクトに暗黙的に変換しませんが、gcc 4.9.1 は変換します。

于 2015-04-08T19:41:26.923 に答える