请考虑以下代码:
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...
然而,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};
^
如果我在g ++ 4.8.1中删除了Foo(const Foo&) = delete;
,那么compiles fine。
我的代码中是否存在错误,一个编译器忽略但另一个编译器没有错误?
答案 0 :(得分:15)
C ++ 11 8.5.1 [dcl.init.aggr] p1定义聚合类型:
聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有大括号或等于初始化静态数据成员(9.2),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3)。
用户提供的在8.4.2中定义[dcl.fct.def.default] p4:
...特殊成员函数是用户提供的,如果它是用户声明的而非显式的 在第一份声明中默认或删除。
Foo
有两个用户声明的构造函数,这两个构造函数在第一个声明时都被显式默认或删除,因此Foo
是一个聚合。
海湾合作委员会错了。