Consider:
struct A {
A (int);
A (const A &);
};
struct B {
A foo [2];
B (const A & x, const A & y)
: foo {x, y} /* HERE IS THE PROBLEM */
{}
};
I was expecting this to work since I'm using C++0x support in GCC4.3, which allegedly supports initialiser lists. No joy.
I have a class A which has no default constructor. This is not negotiable. Assignment post-default is not an option.
I am trying to create B which uses A. B::foo may not be std::vector.
How can I initialise B::foo
in B(...)
, constructing its elements exactly once?
At the moment, I am condidering replacing B with
struct B {
A foo_a;
B foo_b;
A * foo () {
assert ((&foo_b) - *&foo_a) == 1);
return &foo_a;
}
B (const A & x, const A & y) : foo_a(x), foo_b(y) {}
};
Or even using char foo [2*sizeof(A)]
with placement new -- YUK!
Surely there's a proper way to do this?
You can use boost::array
. It has a plain native array inside, so it still has the same memory layout like in your example.
struct B {
boost::array<A, 2> foo;
B (const A & x, const A & y)
: foo(createFoo(x, y))
{}
private:
static boost::array<A, 2> createFoo(const A & x, const A & y) {
boost::array<A, 2> a = {{ x, y }};
return a;
}
};
If you don't have boost you can create your own array
class or use std::tr1
if your compiler has it
template<typename T, std::size_t N>
struct array {
T data[N];
};
That's all you need, but you can add the usual begin
, end
, size
functions and so on to make it more comfortable to use.
Unfortunately, there really is no proper, clean way to do this. Consider it something of a language limitation that results from an awkward mixing of C++ constructors and C style arrays. The C++11 standard addresses this issue, but until then you'll have to settle for a workaround.
Since A
has no default constructor, one possible work-around is to have an array of A*
pointers, and then loop over the array and initialize each one with new
. (Obviously, don't forget to delete
each item in the array in B's destructor, or just use smart pointers.)
It should work in C++0x, but g++ 4.5.0 complains with "bad array initializer". If you replace A foo[2]
with std::vector<A> foo
, it compiles.
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