2013-08-13 20 views
10

Si consideri il seguente codice:Perché questo codice funziona in Clang ++ ma non 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}; 
} 

compilazione con clangore ++ non produce errori:

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

Tuttavia, 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}; 
       ^

Se rimuovo Foo(const Foo&) = delete; allora compiles fine in g ++ 4.8.1.

C'è un errore nel mio codice che un compilatore sta ignorando ma l'altro no?

risposta

15

C++ 11 8.5.1 [dcl.init.aggr] p1 definisce tipi aggregati:

Un aggregato è un array o una classe (Clausola 9) senza costruttori forniti dall'utente (12.1), no iniziatori brace-or-equal- per membri di dati non statici (9.2), nessun membro di dati non statici privato o protetto (clausola 11), nessuna classe di base (clausola 10) e nessuna funzione virtuale (10.3).

fornito dall'utente è definito in 8.4.2 p4 [dcl.fct.def.default]:

... Una funzione membro speciale è fornito dall'utente se è dichiarato dall'utente e non esplicitamente predefinito o eliminato nella sua prima dichiarazione.

Foo ha due costruttori dall'utente dichiarato, entrambi i quali sono esplicitamente in default o cancellati sul loro prima dichiarazione, in modo Foo è un aggregato.

GCC è errato.

MODIFICA: This is in fact GCC bug 52707.

Problemi correlati