How can I initialize an array without copy or move-constructing temporary elements? When the element has an explicitly delete
d copy or move constructor, I can initialize the array only if the element has a default ctor or a ctor with all default arguments and I do one of the following: (a) plainly declare the array, (b) direct initialize and zero initialize the array, or (c) copy initialize and zero initialize the array. Neither direct (but not zero) initialization nor copy (but not zero) initialization compiles.
struct Foo
{
Foo(int n = 5) : num(n) {}
Foo(const Foo&) = delete;
//Foo(Foo&&) = delete; // <-- gives same effect
int num;
};
int main()
{
// Resultant arrays for 'a1', 'a2', and 'a3' are two
// 'Foo' elements each with 'num' values of '5':
Foo a1[2]; // plain declaration
Foo a2[2] {}; // direct initialization and zero initialization
Foo a3[2] = {}; // copy initialization and zero initialization
Foo a4[2] {5, 5}; // direct initialization -> ERROR
Foo a5[2] = {5, 5}; // copy initialization -> ERROR
}
- Are those 3 ways the only ways to initialize arrays without copying/moving temporary elements?
- Do
a1
,a2
, anda3
count as initializations? e.g.a1
is a declaration, but its elements get initial, albeit default, values. - Are any of them bugs? I did this GCC 6.3.0 with C++14 flag.
- Why does copy initialization combined with zero initialization work if it is still under the category of copy initialization?
- In general, are all array initializations with curly braces just construction of temporary elements (unless elided when there is no deletion of copy or move constructors (or does elision not apply to arrays?)) followed by per-element copy, move, or mix of copy and move construction?
Foo a[] = { Foo(5), Foo(5) };
? – GossoonFoo a[] = { Foo(5), Foo(5) };
giveserror: use of deleted function 'Foo::Foo(const Foo&)'
– IntravasationFoo
will be initialized by its constructor. – Unfair