Delete the last type of package of template parameters

I want to use the template parameter package types as parameters for another template, but disable the last parameter.

For instance:

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 .

+6
source share
3 answers

Here is a simple approach that uses std::tuple_element<I, Tuple> along with std::index_sequence<sizeof...(Ts) - 1 to get everything except the last type in the list of variational arguments. Since a package of parameters for indices is necessary, there is an additional indirectness that fits into the database, but can 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...> { }; 
+4
source

Here is my solution that uses C ++ 11:

 template <typename ...P> struct dummy {}; template <template <typename ...> class Obj, typename T, typename ...P> struct internal; template <template <typename ...> class Obj, typename ...P1, typename T, typename ...P2> struct internal<Obj, dummy<P1...>, T, P2...> { using type = typename internal<Obj, dummy<P1..., T>, P2...>::type; }; template <template <typename ...> class Obj, typename ...P1, typename T, typename L> struct internal<Obj, dummy<P1...>, T, L> { using type = Obj<P1..., T>; }; template <template <typename ...> class T, typename ...P> struct subst_all_but_last { using type = typename internal<T, dummy<>, P...>::type; }; 

Use this:

 using bar = typename subst_all_but_last<some_template, Ts...>::type; 

instead

 using bar = some_template<magically_get_all_but_last(Ts)...>; 
+3
source

It works:

 #include <tuple> #include <utility> #include <cstdint> using std::size_t; using std::tuple; namespace { template <class Tuple, template <class...> class Template> struct apply_tuple_params_impl {}; template <template <class...> class Template, class... Params> struct apply_tuple_params_impl<tuple<Params...>, Template> { typedef Template<Params...> type; }; template <class Param, class Tuple> struct extend_tuple; template <class Param, class... Params> struct extend_tuple<Param, tuple<Params...>> { typedef tuple<Param, Params...> type; }; template <class Param, class... Params> struct all_but_last_type_tuple_impl { typedef typename extend_tuple<Param, typename all_but_last_type_tuple_impl<Params...>::type>::type type; }; template <class Param> struct all_but_last_type_tuple_impl<Param> { typedef tuple<> type; }; } // pass the template parameters of a tuple to another template template <class Tuple, template <class...> class Template> using apply_tuple_params = typename apply_tuple_params_impl<Tuple, Template>::type; // a tuple type with all the parameters except the last template <class... Params> using all_but_last_type_tuple = typename all_but_last_type_tuple_impl<Params...>::type; 

And use it as follows:

 template <class... Ts> struct some_template; template <class... Ts> struct foo { typedef apply_tuple_params<all_but_last_type_tuple<Ts...>, some_template> bar; }; static_assert(std::is_same<foo<int, bool, std::string>::bar, some_template<int,bool> >::value, ""); 
0
source

All Articles