2013-08-13 42 views
10

Xét đoạn mã sau:Tại sao mã này hoạt động trong Clang ++ chứ không phải 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}; 
} 

Biên soạn với kêu vang ++ mang lại không có lỗi:

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

Tuy nhiên, 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}; 
       ^

Nếu tôi loại bỏ Foo(const Foo&) = delete; sau đó nó compiles fine trong g ++ 4.8.1.

Có lỗi trong mã của tôi mà một trình biên dịch bỏ qua nhưng trình biên dịch khác không phải là lỗi?

Trả lời

15

C++ 11 8.5.1 [dcl.init.aggr] p1 định nghĩa các loại tổng hợp:

Một tổng là một mảng hoặc một lớp học (khoản 9) không có nhà xây dựng người dùng cung cấp (12.1), không có bộ khởi tạo dấu ngoặc đơn hoặc bằng nhau cho thành viên dữ liệu không tĩnh (9.2), không có thành viên dữ liệu không được bảo mật hoặc riêng tư (Điều 11), không có lớp cơ sở (Điều 10) và không có chức năng ảo (10.3).

dùng cung cấp được định nghĩa trong 8.4.2 p4 [dcl.fct.def.default]:

... Một hàm thành viên đặc biệt là dùng cung cấp nếu nó là người dùng khai báo và không rõ ràng được mặc định hoặc bị xóa trên khai báo đầu tiên.

Foo có hai hàm tạo do người dùng khai báo, cả hai đều được đặt mặc định hoặc xóa trên khai báo đầu tiên, vì vậy Foo là tổng hợp.

GCC sai.

EDIT: This is in fact GCC bug 52707.

Các vấn đề liên quan