Is it possible to initialize all elements of std::tuple
by the same argument, using the non-default constructors of the underlying types?
template <typename... TElements>
struct Container {
// I'd wish to be able to do something like this:
Container(Foo foo, Bar bar)
: tuple(foo, bar)
{}
std::tuple<TElements...> tuple;
};
The point is that I don't know the tuple size (it's templated by a variadic parameter), so I can't duplicate the arguments as many times as I need. The only thing I know is that all types in TElements
have a constructor taking Foo
and Bar
as arguments and don't have a default constructor.
The clearest way is just to construct each element in the tuple
constructor argument list:
template <typename... TElements>
struct Container {
Container(Foo foo, Bar bar)
: tuple(TElements{foo, bar}...)
{}
std::tuple<TElements...> tuple;
};
This will result in move (or copy) constructing each element of the tuple from its corresponding constructor parameter; if this is unacceptable you could use piecewise construction:
template <typename... TElements>
struct Container {
Container(Foo foo, Bar bar)
: tuple(std::piecewise_construct, (sizeof(TElements), std::tie(foo, bar))...)
{}
std::tuple<TElements...> tuple;
};
Unfortunately in this case we have to do some kind of gymnastics (here sizeof
and a comma operator) to get the variadic list TElements
mentioned and ignored.