C++ doesn't allow a class containing an array of items that are not default constructible:
class Gordian {
public:
int member;
Gordian(int must_have_variable) : member(must_have_variable) {}
};
class Knot {
Gordian* pointer_array[8]; // Sure, this works.
Gordian inlined_array[8]; // Won't compile. Can't be initialized.
};
As even beginner C++ users know, the language guarantees that all members are initialized when constructing a class. And it doesn't trust the user to initialize everything in the constructor - one has to provide valid arguments to the constructors of all members before the body of the constructor even starts.
Generally, that's a great idea as far as I'm concerned, but I've come across a situation where it would be a lot easier if I could actually have an array of non-default constructible objects.
The obvious solution: Have an array of pointers to the objects. This is not optimal in my case, as I am using shared memory. It would force me to do extra allocation from an already contended resource (that is, the shared memory). The entire reason I want to have the array inlined in the object is to reduce the number of allocations.
This is a situation where I would be willing to use a hack, even an ugly one, provided it works. One possible hack I am thinking about would be:
class Knot {
public:
struct dummy { char padding[sizeof(Gordian)]; };
dummy inlined_array[8];
Gordian* get(int index) {
return reinterpret_cast<Gordian*>(&inlined_array[index]);
}
Knot() {
for (int x = 0; x != 8; x++) {
new (get(x)) Gordian(x*x);
}
}
};
Sure, it compiles, but I'm not exactly an experienced C++ programmer. That is, I couldn't possibly trust my hacks less. So, the questions:
1) Does the hack I came up with seem workable? What are the issues? (I'm mainly concerned with C++0x on newer versions of GCC).
2) Is there a better way to inline an array of non-default constructible objects in a class?