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