The existing question on Why can't I initialise an array of objects if they have private copy constructors? specifically refers to C++03. I know from that question that what I am trying to do is not allowed in C++03 but I thought that it should be possible in C++11
I have a non-movable class (call it Child) and I need to initialize an array of Child in the constructor of another class (call it Parent). By "non-movable" I mean that the address of a Child object has to remain the same during that object's lifetime. What is the correct way to do this?
With C++11 I've tried the following:
class Child
{
public:
Child (int x) {}
~Child () {}
Child (const Child &) = delete;
};
class Parent
{
public:
Parent () : children {{5}, {7}} {}
private:
Child children[2];
};
This code compiles fine with Clang 3.5.0, but GCC 4.9.1 complains that I am trying to use the deleted copy constructor:
test.cc: In constructor ‘Parent::Parent()’:
test.cc:13:35: error: use of deleted function ‘Child::Child(const Child&)’
Parent () : children {{5}, {7}} {}
^
test.cc:7:5: note: declared here
Child (const Child &) = delete;
^
I've read about the difference between copy-initialization and direct-initialization (here and here, for example), and I want to avoid calling the copy constructor by using direct-initialization. Am I getting the syntax wrong? Is this a bug in GCC? Or is what I am trying to do just not possible?
children {Child{5}, Child{7}}
, which should behave identically to what you've posted. A workaround would be to use avector
and emplace theChild
objects. – StralsundChild children[2] { {5}, {7} };
which should be identical to the version where the same initializer occurs in the ctor initializer list; both are covered by [dcl.init.list]/3 – Agreechildren[2] = { {5}, {7} }
says thatchildren[0]
is copy-initializaed from{5}
, i.e. it's the same asChild c = { 5 };
, and that is covered by [dcl.init.list] again which invokes the constructor forc
that takesint
(without involving a copy). – Agreechildren {Child {5}, Child {7}}
is different, I think. PuttingChild {5}
inside the braces forces the compiler to (nominally) create a temporary object which is then copied to initialize the array. – Broider