没有临时数组的列表初始化 - 在 GCC 中不起作用

List-initialization of an array without temporaries - not working in GCC

本文关键字:GCC 不起作用 初始化 列表 数组      更新时间:2023-10-16

考虑以下人为的例子

struct A {
    A(int) {}
    A(const A&) = delete;
    ~A() {}
};
struct B {
    A a[2] = {{1}, {2}};
};
int main() {
    B b;
}

它在clang(任何版本(中编译良好,但在GCC(任何版本,任何标准>= C++11(中编译不行

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

现场演示

当 A 的析构函数被注释掉时,它在 GCC 中也能很好地编译。

问题是 - 谁是对的,叮当还是 GCC,为什么?

最初我认为GCC是错误的,但后来我看到了[dcl.init.list]/5,其中指出创建了临时文件。虽然我不确定这是否适用于这里,或者是否有其他规则覆盖了这一点。

由于数组是一个聚合,聚合初始化归结为从相应的初始值设定项子句对聚合成员进行复制初始化,问题基本上是:复制列表初始化(分别来自{1}{2}的数组元素a[0]a[1](是否需要复制构造函数,但这样的问题已经得到了回答——它不需要。

顺便说一句,GCC 接受A a = {1};,即它在"直接"复制列表初始化方面没有问题,但在聚合成员初始化时没有正确处理它。