解包std :: pair <t,std :: pair <u,std :: pair <... =“”>&gt;&gt; to tuple <t,u,...> </t,u,...> </t,std :: pair <u,>

时间:2013-06-25 01:15:07

标签: templates c++11 tuples std-pair stdtuple

所以我试图提出一个转换a;

的函数
std::pair<T,std::pair<U, V>>

数据类型,转换为std::tuple;

std::tuple<T,U,V>

它应该在一般情况下工作,具有任意数量的混合类型参数,对的格式是;

  • 'car'将始终是一种类型,
  • 'cdr'将永远是std::pair
    • 除了最里面的情况,'cdr'将是一个类型本身
      (但这可能是std::pair本身,因为类型是任意的。)

我想要检索的参数的数量和类型是通过可变参数模板参数预先知道的。

我目前的进展有点低,我一直在尝试一些事情,但似乎我需要的代码就是这些;

std::make_tuple(get<0>(pair), get<0>(get<1>(pair), get<0>(get<1>(get<1>(pair), ..., get<1>(pair)))));

但是我似乎无法找到自动生成此方法的方法,我尝试了Sequence<int...>方法,但是没有运气,但是我确实认为这是我需要考虑的那些方面,例如一个get方法,它使用可变数量的索引,并使用普通的get方法使用这些索引多次查找?

1 个答案:

答案 0 :(得分:2)

简单递归怎么样

#include <utility>
#include <tuple>

// 1. metafunction to concatenate a type and a tuple
template<typename T, typename U> struct tuple_prepend_type;

template<typename T, typename ...U>
struct tuple_prepend_type<T, std::tuple<U...>>
{
    using type = std::tuple<T, U...>;
};

// 2. is_pair type trait
template<typename>
struct is_pair : std::false_type {};
template<typename U, typename V>
struct is_pair<std::pair<U, V>> : public std::true_type {};

// 3. the converter itself
template<typename T, typename = void>
struct pairs_to_tuple {
    using type = std::tuple<typename T::first_type,
                            typename T::second_type>;
};

template<typename T>
struct pairs_to_tuple<T, typename std::enable_if<
                         is_pair<typename T::second_type>::value
                     >::type
         >
{
    using type = typename tuple_prepend_type<
                     typename T::first_type,
                     typename pairs_to_tuple<typename T::second_type>::type
                 >::type;
};

int main()
{
    std::pair<int, std::pair<double, std::pair<bool, char> > > p;
    static_assert(std::is_same<pairs_to_tuple<decltype(p)>::type,
                               std::tuple<int, double, bool, char>>::value, "")
}