If I understand your intention correctly, it looks like what you want is to pass M
arguments to a std::tuple<>
of size N
, where M <= N
. If M < N
, fill in the arguments that aren't provided with default constructed values of the type.
If that's the case, the constructor for Base
should be:
template <class... OtherTypes>
explicit inline Base(const OtherTypes&... source)
: _data(transmute<std::tuple<Types...>>(source...))
{;}
So that it will go through the recursive, final, then forward_as_tuple
.
Alternative Solution:
NOTE: Implementation of std::integer_sequence
and related helpers are omitted. You can refer to the paper N3658 and an implementation here.
template <typename T, typename Seq, T Begin>
struct make_integer_range_impl;
template <typename T, T... Ints, T Begin>
struct make_integer_range_impl<T, std::integer_sequence<T, Ints...>, Begin>
: public std::common_type<std::integer_sequence<T, Begin + Ints...>> {};
/* Similar to std::make_integer_sequence<>, except it goes from [Begin, End)
instead of [0, Size). */
template <typename T, T Begin, T End>
using make_integer_range = typename make_integer_range_impl<
T, std::make_integer_sequence<T, End - Begin>, Begin>::type;
/* Similar to std::make_index_sequence<>, except it goes from [Begin, End)
instead of [0, Size). */
template <std::size_t Begin, std::size_t End>
using make_index_range = make_integer_range<std::size_t, Begin, End>;
/* Trivial wrapper for std::tuple_element<>. */
template <std::size_t Idx, typename Tuple>
using tuple_element_t = typename std::tuple_element<Idx, Tuple>::type;
template <typename... Args>
class Partial {
public:
/* Our tuple type. */
using Tuple = std::tuple<Args...>;
/* Create an index_range, [# of arguments, tuple size),
and forward the arguments to the delegating constructor. */
template <typename... ForwardArgs>
Partial(ForwardArgs &&... forward_args)
: Partial(make_index_range<sizeof...(ForwardArgs),
std::tuple_size<Tuple>::value>(),
std::forward<ForwardArgs>(forward_args)...) {}
private:
/* The given indices are for the missing arguments, get the corresponding
types out of the tuple and default construct them. */
template <std::size_t... Indices, typename... ForwardArgs>
Partial(std::index_sequence<Indices...> &&, ForwardArgs &&... forward_args)
: tuple_{std::forward<ForwardArgs>(forward_args)...,
tuple_element_t<Indices, Tuple>{}...} {}
/* Our tuple instance. */
Tuple tuple_;
}; // Partial<Args...>