10

次のコードを検討してください。

struct Foo
{
    int x, y;

    Foo() = default;
    Foo(const Foo&) = delete;
    Foo& operator=(const Foo&) = delete;
};

int main()
{
    Foo f1 {1, 2};
    Foo f2 = {1, 2};
}

clang++ でコンパイルしてもエラーは発生しません。

$ clang++ --version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
$ clang++ -std=c++11 -stdlib=libc++ -pedantic t.cpp -o out
...builds and runs fine...

ただし、ideone を使用して g++ 4.8.1 でコンパイルすると、次のエラーが発生します。

prog.cpp: In function ‘int main()’:
prog.cpp:12:17: error: no matching function for call to ‘Foo::Foo(<brace-enclosed initializer list>)’
     Foo f1 {1, 2};
                 ^
prog.cpp:12:17: note: candidate is:
prog.cpp:5:5: note: Foo::Foo()
     Foo() = default;
     ^
prog.cpp:5:5: note:   candidate expects 0 arguments, 2 provided
prog.cpp:13:19: error: could not convert ‘{1, 2}’ from ‘&lt;brace-enclosed initializer list>’ to ‘Foo’
     Foo f2 = {1, 2};
                   ^

削除すると、g++ 4.8.1 で正常Foo(const Foo&) = delete;コンパイルされます。

私のコードには、一方のコンパイラーは無視しているが、もう一方のコンパイラーは無視していないというエラーがありますか?

4

1 に答える 1

15

C++11 8.5.1 [dcl.init.aggr] p1 は集計タイプを定義します。

集合体は、ユーザー提供のコンストラクター (12.1)、非静的データ メンバーのブレースまたはイコール初期化子(9.2)、プライベートまたは保護された非静的データ メンバー (条項 11)、基本クラスなし (条項 10)、および仮想関数なし (10.3)。

ユーザー提供は 8.4.2 [dcl.fct.def.default] p4 で定義されています。

...ユーザーが宣言し、最初の宣言で明示的にデフォルト設定または削除されていない場合、特別なメンバー関数はユーザー提供です。

Fooには 2 つのユーザー宣言コンストラクターがあり、どちらも最初の宣言で明示的にデフォルト設定または削除されるためFoo、集約です。

GCCは間違っています。

編集:これは実際には GCC バグ 52707です。

于 2013-08-13T18:41:58.610 に答える