rus*_*tyx 15 c++ gcc language-lawyer c++11
考虑下面的人为例子
struct A {
A(int) {}
A(const A&) = delete;
~A() {}
};
struct B {
A a[2] = {{1}, {2}};
};
int main() {
B b;
}
Run Code Online (Sandbox Code Playgroud)
它可以在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;
^
Run Code Online (Sandbox Code Playgroud)
当A的析构函数被注释掉时,它在GCC中也可以正常编译。
问题是 -谁是正确的,lang还是GCC,为什么?
最初我以为GCC是错误的,但是后来我看到[dcl.init.list] / 5指出创建了临时文件。虽然我不确定这是否适用于此处,或者是否有其他规则可以覆盖此规则。
由于数组是一个聚合,并且聚合初始化归结为来自相应初始化子句的聚合成员的复制初始化,因此问题基本上是:复制列表初始化(分别是数组元素a[0]和a[1]from{1}和{2})是否需要复制构造函数,但这样的问题已经得到解答\xe2\x80\x94 它没有。
顺便说一句,GCC 接受A a = {1};,即它对“直接”复制列表初始化没有问题,但在初始化聚合成员时不能正确对待它。