Consider the following contrived example
struct A {
A(int) {}
A(const A&) = delete;
~A() {}
};
struct B {
A a[2] = {{1}, {2}};
};
int main() {
B b;
}
It compiles fine in clang (any version) but not in GCC (any version, any standard >= 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;
^
LIVE DEMO
When A's destructor is commented out, it compiles fine also in GCC.
Question is - who is right, clang or GCC, and why?
Initially I thought GCC is wrong, but then I saw [dcl.init.list]/5 which states that temporaries are created. Though I'm not sure if that applies here or if there's another rule that overrides this.
Since an array is an aggregate and aggregate initialization comes down to copy-initialization of aggregate members from the corresponding initializer-clauses, the question basically is: does copy-list-initialization (of array elements a[0]
and a[1]
from {1}
and {2}
, respectively) require copy constructor, but such question has already been answered — it does not.
BTW, GCC accepts A a = {1};
, i.e. it has no problem with "direct" copy-list-initialization, but does not treat it correctly when members of aggregates are initialized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With