I got a struct B
that is derived from a struct A
.
struct A{
int a;
};
struct B : public A{
int b;
};
Is there a straight way to initialize an object of type B
without providing a constructor, let's say using initializer-list?
Some more insight:
I got two struct
s that I use to pass data between threads; the second one holds the same data as the first one, with the addition of some synchronization variable. I could make the first struct
a data member of the second one, or just duplicate the declaration of data members in the second struct
, to easily use the initializer-list; but I think that in this particular application it would be logically more correct that the second struct
extends the first one.
There isn't an extremely concise solution, but there is a solution at least:
#include <type_traits>
#include <utility>
struct B : A
{
int b;
template <typename ...Args,
typename = typename std::enable_if<
std::is_constructible<A, Args&&...>::value>
B(int x, Args &&... args)
: b(x), A(std::forward<Args>(args)...)
{ }
};
This solution isn't exactly short, but it is general. The new constructor for B
exists only in those specializations which make sense, thanks to the enable-if SFINAE, so B
is precisely as constructible as it can be.
There is one more danger here that I didn't address, namely how explicit
the new constructor should be. Ideally it should be as explicit as the matching A
constructor, but that's a bit hard to detect programatically (as done in N4064 for pairs and tuples).