如何拆分元组?

Tam*_*lei 18 c++ c++11

给出一个

   template<typename First, typename... Tail>
   struct something
   {
       std::tuple<First, Tail...> t;
   };
Run Code Online (Sandbox Code Playgroud)

如何获得std::tuple<Tail...>包含t除第一个元素之外的所有元素的元素?


我认为这是一个有趣的问题,但这是我对背景的动机:

我想为元组实现哈希.我用这个答案作为基础.我发现它有一个错误,即没有调用operator()带有值的哈希对象:

return left() ^ right();
Run Code Online (Sandbox Code Playgroud)

应该:

return left(std::get<0>(e)) ^ right(???);
Run Code Online (Sandbox Code Playgroud)

??? 将是元组的剩余元素继续模板的递归实例化.以下是完整的代码,包括终止部分:

#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;
    }
};

}
Run Code Online (Sandbox Code Playgroud)

And*_*ner 13

我正在寻找相同的东西,并提出了这个相当直接的C++ 14解决方案:

#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;
}
Run Code Online (Sandbox Code Playgroud)

因此,head(.)返回元组的第一个元素,tail(.)返回仅包含最后N-1个元素的新元组.


Ker*_* SB 1

像这样的东西:

#include <tuple>

template <bool, typename T, unsigned int ...N> struct tail_impl;

template <typename T, typename ...Args, unsigned int ...N>
struct tail_impl<false, std::tuple<T, Args...>, N...>
{
    static std::tuple<Args...> go(std::tuple<T, Args...> const & x)
    {
        return tail_impl<sizeof...(N) + 1 == sizeof...(Args), std::tuple<T, Args...>, N..., sizeof...(N)>::go(x);
    }
};

template <typename T, typename ...Args, unsigned int ...N>
struct tail_impl<true, std::tuple<T, Args...>, N...>
{
    static std::tuple<Args...> go(std::tuple<T, Args...> const & x)
    {
        return std::tuple<Args...>(std::get<N>(x)...);
    }
};

template <typename T, typename ...Args>
std::tuple<Args...> tail(std::tuple<T, Args...> const & x)
{
    return tail_impl<sizeof...(Args) == 1, std::tuple<T, Args...>, 0>::go(x);
}
Run Code Online (Sandbox Code Playgroud)

测试:

#include <demangle.hpp>
#include <iostream>

typedef std::tuple<int, char, bool> TType;

int main()
{
    std::cout << demangle<TType>() << std::endl;
    std::cout << demangle<decltype(tail(std::declval<TType>()))>() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

印刷:

std::tuple<int, char, bool>
std::tuple<char, bool>
Run Code Online (Sandbox Code Playgroud)

  • 我的测试: `int main() { std::tuple&lt;int,char,double&gt; t1(42,'e',16.7); std::tuple&lt;char,double&gt; t2 = tail(t1); std::cout &lt;&lt; std::get&lt;0&gt;(t2) &lt;&lt; std::endl; }` 编译失败:`错误:无法调用成员函数 'std::tuple&lt;Args ...&gt; tail_impl&lt;false, std::tuple&lt;T, Args ...&gt;, N ...&gt;::go( const std::tuple&lt;T, Args ...&gt;&amp;) [with T = int, Args = {char, double}, unsigned int ...N = {0u}]' 不带对象` (2认同)