Tobias Brandt Tobias Brandt - 2 months ago 27
C++ Question

Remove the last type of a template parameter pack

I want to use the types of a template parameter pack as parameters to a different template, but cut off the last parameter.

For example:

template <class... Ts> struct some_template;

template <class... Ts> struct foo
{
using bar = some_template<magically_get_all_but_last(Ts)...>;
};

// I might be missing a few "typename"s, but you get the idea.
static_assert(std::is_same<foo<int, bool, std::string>::bar, some_template<int,bool> >::value);


Note that this is the opposite of getting only the last parameter.

Answer

Here is a simple approach which use std::tuple_element<I, Tuple> together with std::index_sequence<sizeof...(Ts) - 1 to get all but the last type in a list of variadic arguments. Since the parameter pack for the indices is needed, there is an extra indirection which is put into a base but could be anywhere.

template <class T, class... Ts> struct foobase;
template <std::size_t... I, class... Ts>
struct foobase<std::index_sequence<I...>, Ts...> {
    using bar = some_template<typename std::tuple_element<I, std::tuple<Ts...>>::type...>;
};

template <class... Ts> struct foo
    : foobase<std::make_index_sequence<sizeof...(Ts) - 1>, Ts...>
{
};