Suppose we want to create a helper class for a reverse package template, for example. in the following way:
#include <tuple> #include <utility> #include <typeinfo> #include <iostream> template <class> struct sizer; template <template<class...> class Pack, class... Args> struct sizer<Pack<Args...>> { static constexpr size_t value = sizeof...(Args); }; template <class Pack, class Indices = std::make_index_sequence<sizer<Pack>::value>> struct reverse_pack; template <class... Args, size_t... I> struct reverse_pack<std::tuple<Args...>, std::integer_sequence<std::size_t, I...>> { using type = typename std::tuple<typename std::tuple_element<(sizeof...(Args) - I - 1), std::tuple<Args...>>::type...>; }; int main() { std::cout << typeid(reverse_pack<std::tuple<int, float, double>>::type).name() << std::endl; }
We could successfully do the same, using, for example, as a template parameter:
#include <utility> #include <typeinfo> #include <iostream> template <class> struct sizer; template <class... Args> struct sizer<void(Args...)> { static constexpr size_t value = sizeof...(Args); }; template <size_t N, class Sign> struct nth_param; template <size_t N, class First, class... Args> struct nth_param<N, void(First, Args...)>: nth_param<N-1, void(Args...)> { }; template <class First, class... Args> struct nth_param<0, void(First, Args...)> { using type = First; }; template <class Pack, class Indices = std::make_index_sequence<sizer<Pack>::value>> struct reverse_pack; template <class... Args, size_t... I> struct reverse_pack<void(Args...), std::integer_sequence<std::size_t, I...>> { using type = void(typename nth_param<(sizeof...(Args) - I - 1), void(Args...)>::type...); }; int main() { std::cout << typeid(reverse_pack<void(int, float, double)>::type).name() << std::endl; }
My experience with std::tuple (for example, here ) shows that it is designed to store data, and not to transfer type packets between templates. So, are there any practical reasons to use a tuple to work with variators?