为什么这段代码在Clang++中能运行但在G++中不能?

10

考虑以下代码:

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

然而,通过ideone使用g++4.8.1进行编译会产生错误

prog.cpp: In functionint main()’:
prog.cpp:12:17: error: no matching function for call toFoo::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};
                   ^

如果我删除 Foo(const Foo&) = delete;,那么在 g++4.8.1 中可以编译成功,这里是示例代码

我的代码是否存在错误,导致一个编译器忽略了它,而另一个则没有?

1个回答

15
C++11 8.5.1 [dcl.init.aggr] p1定义了聚合类型:

聚合体是没有用户提供的构造函数(12.1), 非静态数据成员没有花括号或等号初始化(9.2), 没有私有或保护非静态数据成员(Clause 11), 没有基类(Clause 10)和虚函数(10.3)的数组或类(Clause 9)。

user-provided 定义在8.4.2 [dcl.fct.def.default] p4中:

... 如果一个特殊成员函数是用户声明的且在第一次声明中未显式默认或删除,则它是用户提供的

Foo 有两个用户声明的构造函数,两者都在其第一次声明上明确默认或删除,因此Foo是一个聚合体。
GCC是错误的。
编辑:事实上这是 GCC bug 52707

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接