C++ 列出没有临时变量的数组初始化-不在GCC中工作
考虑以下人为的例子C++ 列出没有临时变量的数组初始化-不在GCC中工作,c++,c++11,gcc,language-lawyer,C++,C++11,Gcc,Language Lawyer,考虑以下人为的例子 struct A { A(int) {} A(const A&) = delete; ~A() {} }; struct B { A a[2] = {{1}, {2}}; }; int main() { B b; } 它在clang(任何版本)中编译得很好,但在GCC(任何版本,任何标准>=C++11)中编译得不好 :在构造函数“constexpr B::B()”中: :7:8:错误:使用已删除的函数“A::A(常量A&)
struct A {
A(int) {}
A(const A&) = delete;
~A() {}
};
struct B {
A a[2] = {{1}, {2}};
};
int main() {
B b;
}
它在clang(任何版本)中编译得很好,但在GCC(任何版本,任何标准>=C++11)中编译得不好
:在构造函数“constexpr B::B()”中:
:7:8:错误:使用已删除的函数“A::A(常量A&)”
结构B{
^
:3:5:注:此处声明
A(常数A&)=删除;
^
:在函数“int main()”中:
:12:7:注意:此处首先需要合成方法“constexpr B::B()”
B B;
^
当一个函数的析构函数被注释掉时,它在GCC中也能很好地编译
问题是——谁是对的,是clang还是GCC,为什么
起初我认为GCC是错误的,但后来我看到了创建临时表的状态。虽然我不确定这是否适用于这里,或者是否有另一条规则覆盖了这一点。因为和,问题基本上是:复制列表初始化(数组元素a[0]
和a[1]
来自{1}
和{2}
分别需要复制构造函数,但已经是了-它没有
顺便说一句,GCC接受
A={1};
,也就是说,它在“直接”复制列表初始化方面没有问题,但在初始化聚合成员时没有正确处理它。[dcl.init.list]/5
不适用,因为您正在对a
进行聚合初始化。即使可以省略副本,副本构造函数也需要存在。@NathanOliver-a不是聚合,因为它有一个构造函数。但是a[2]
是的聚合可能的副本
<source>: In constructor 'constexpr B::B()':
<source>:7:8: error: use of deleted function 'A::A(const A&)'
struct B {
^
<source>:3:5: note: declared here
A(const A&) = delete;
^
<source>: In function 'int main()':
<source>:12:7: note: synthesized method 'constexpr B::B()' first required here
B b;
^