Creating a new tuple class by popping the last type
c++11, variadic-templates
Solution
`tuple<Ts..., E>` is a non-deduced context. [temp.deduct.type]/9:
If `P` has a form that contains `<T>` or `<i>`, then each argument `P`i of the respective template argument list `P` is compared with the corresponding argument `A`i of the corresponding template argument list of `A`. If the template argument list of `P` contains a pack expansion that is not the last template argument, the entire template argument list is a non-deduced context.
That means that your partial specialization is never matched.
With C++14, one could use
template <class T, class=std::make_index_sequence<std::tuple_size<T>::value-1>>
struct pop;
template <typename Tuple, std::size_t... indices>
struct pop<Tuple, std::index_sequence<indices...>>
{
using type = std::tuple<std::tuple_element_t<indices, Tuple>...>;
};
template <typename T>
using pop_t = typename pop<T>::type;
Such that
using t = std::tuple<int, char, float>;
static_assert( std::is_same<pop_t<t>, std::tuple<int, char>>{}, "" );
Compiles.
Demo.
Problem
I tried the following code but it gives: main.cpp:29:22: error: aggregate `'pop<std::tuple<int, char, float> > p'` has incomplete type and cannot be defined What am I missing? ``` template <typename T> struct pop; template <typename E, typename... Ts> struct pop<tuple<Ts..., E>> { using result = tuple<Ts...>; }; tuple<int, char, float> t; typename pop<decltype(t)>::result p; ``` If Ts... must be at the end in a type list, why does it work in this example from http://en.cppreference.com/w/cpp/language/parameter_pack: ``` template<class A, class B, class...C> void func(A arg1, B arg2, C...arg3) { container<A,B,C...> t1; // expands to container<A,B,E1,E2,E3> container<C...,A,B> t2; // expands to container<E1,E2,E3,A,B> container<A,C...,B> t3; // expands to container<A,E1,E2,E3,B> } ```