2013-08-13 15 views
10

Betrachten Sie den folgenden Code ein:Warum funktioniert dieser Code in Clang ++, aber nicht in G ++?

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

mit Klirren Kompilieren ++ liefert keine Fehler:

$ 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... 

jedoch compiling with g++ 4.8.1 through ideone gives errors:

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 ‘<brace-enclosed initializer list>’ to ‘Foo’ 
    Foo f2 = {1, 2}; 
       ^

Wenn ich es Foo(const Foo&) = delete; dann compiles fine in g entfernen ++ 4.8.1.

Gibt es einen Fehler in meinem Code, den ein Compiler ignoriert, aber der andere nicht?

Antwort

15

C++ 11 8.5.1 [dcl.init.aggr] p1 definiert Aggregattypen:

Ein Aggregat ist ein Array oder eine Klasse (Abschnitt 9) ohne Benutzer bereitgestellten Konstruktoren (12.1), no brace-or-equal-initializers für nicht statische Datenelemente (9.2), keine privaten oder geschützten nicht statischen Datenelemente (Abschnitt 11), keine Basisklassen (Abschnitt 10) und keine virtuellen Funktionen (10.3).

Benutzer bereitgestellten wird in 8.4.2 [dcl.fct.def.default] p4 definiert:

... eine spezielle Elementfunktion ist Benutzer bereitgestellten wenn es user-deklariert und nicht explizit voreingestellt oder gelöscht auf seiner ersten Deklaration.

Foo hat zwei benutzer deklarierten Konstruktoren, welche beide ausdrücklich vorgegeben sind oder auf ihrer ersten Erklärung gelöscht, so Foo ein Aggregat ist.

GCC ist falsch.

EDIT: This is in fact GCC bug 52707.

Verwandte Themen