How to split a tuple?

c++, c++11

Solution

I was searching for the same thing and came up with this rather straight forward C++14 solution:

#include <iostream>
#include <tuple>
#include <utility>

template < typename T , typename... Ts >
auto head( std::tuple<T,Ts...> t )
{
   return  std::get<0>(t);
}

template < std::size_t... Ns , typename... Ts >
auto tail_impl( std::index_sequence<Ns...> , std::tuple<Ts...> t )
{
   return  std::make_tuple( std::get<Ns+1u>(t)... );
}

template < typename... Ts >
auto tail( std::tuple<Ts...> t )
{
   return  tail_impl( std::make_index_sequence<sizeof...(Ts) - 1u>() , t );
}

int main()
{
   auto t = std::make_tuple( 2, 3.14 , 'c' );
   std::cout << head(t) << std::endl;
   std::cout << std::get<0>( tail(t) ) << std::endl;
   std::cout << std::get<1>( tail(t) ) << std::endl;
}

So, head(.) returns the first element of a tuple and tail(.) returns a new tuple containing only the last N-1 elements.

Problem

Given a ``` template<typename First, typename... Tail> struct something { std::tuple<First, Tail...> t; }; ``` How can I get a `std::tuple<Tail...>` that contains all elements from `t` except for the first one? I think this is an interesting question in general, but here is my motivation for context: I'd like to implement a hash for tuples. I used this answer as a basis. I found that there was an error in it, namely not calling `operator()` of the hash object with a value: ``` return left() ^ right(); ``` Should be: ``` return left(std::get<0>(e)) ^ right(???); ``` The ??? would be the remaining elements of the tuple to continue the recursive instantiation of the template. Here is the complete code including the termination part: ``` #include <functional> #include <utility> namespace std { template<typename First, typename... Tail> struct hash<std::tuple<First, Tail...>> { typedef size_t result_type; typedef std::tuple<First, Tail...> argument_type; result_type operator()(argument_type const& e) const { std::hash<First> left; std::hash<std::tuple<Tail...>> right; return left(std::get<0>(e)) ^ right(???); } }; template<> struct hash<std::tuple<>> { typedef size_t result_type; typedef std::tuple<> argument_type; result_type operator()(argument_type const& e) const { return 1; } }; } ```

Original source

Related problems