2013-08-13 7 views
10

Rozważmy następujący kod:Dlaczego ten kod działa w języku Clang ++, ale nie w 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}; 
} 

kompilacji z brzękiem ++ daje żadnych błędów:

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

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

Jeśli usunąć Foo(const Foo&) = delete; wtedy compiles fine w g ++ 4.8.1.

Czy wystąpił błąd w moim kodzie, że jeden kompilator ignoruje, a drugi nie?

Odpowiedz

15

C++ 11 8.5.1 [dcl.init.aggr] p1 kruszywa określa typy:

agregat jest tablicą lub klasy (Rozdział 9) bez konstruktorów dostarczane przez użytkowników (12.1), nr ortokwasów lub równych inicjatorów dla niestatycznych elementów danych (9.2), bez prywatnych lub chronionych niestatycznych elementów danych (klauzula 11), bez klas bazowych (klauzula 10) i bez funkcji wirtualnych (10.3).

wprowadzona przez użytkownika jest zdefiniowana w 8.4.2 [dcl.fct.def.default] p4:

... Specjalny element funkcja jest wprowadzona przez użytkownika jeśli jest zadeklarowany przez użytkownika i nie jawnie domyślny lub usunięty w swojej pierwszej deklaracji.

Foo ma dwa konstruktory zadeklarowana przez użytkownika, z których oba są wyraźnie niewykonaniem lub usunięte na ich pierwszej deklaracji, więc Foo jest agregatem.

GCC jest błędne.

EDYTOWANIE: This is in fact GCC bug 52707.

Powiązane problemy