通过将两个参数包的元素线程化为成对的类型来解包

时间:2019-06-08 07:44:30

标签: c++ variadic-templates template-meta-programming

假设有l.groupBy(_._1).mapValues(_.map(_._2).reduce(_ + _)).toList 个用户指定的类型,我想一个函数返回一个长度为N的{​​{1}},其中每个元素都是通过对某个函数的函数调用构造的(示例在下面的std::tuple中):

N

本质上,我的问题是我如何解压缩参数以沿“ type0,0”,“ type1,1”等行获取内容,而不是“ type0,type1,...,0,1,”。 ..”,如果有道理。

这是一个常见问题,是否有惯用的解决方案?

1 个答案:

答案 0 :(得分:3)

如果size_t参数是0, 1, ...,则可以简单地使用其他间接级别:

template<class Tuple, std::size_t... I> 
Tuple build_tuple_impl(std::index_sequence<I...>)
{
    return std::make_tuple(
        func<std::tuple_element_t<I, Tuple>>(I)...);
}

template<typename... Ts> 
auto build_tuple()
{
    using Tuple = std::tuple<Ts...>;
    return build_tuple_impl<Tuple>(std::make_index_sequence<sizeof...(Ts)>{});
}

// Usage:
auto t = build_tuple<std::string, int, int>();

更一般的情况:

template<class Tuple, std::size_t... Is, std::size_t... I> 
Tuple build_tuple_impl(std::index_sequence<Is...>, std::index_sequence<I...>)
{
    constexpr std::size_t is[] = {Is...};
    return std::make_tuple(
        func<std::tuple_element_t<I, Tuple>>(is[I])...);
}

template<typename... Ts, std::size_t... Is>
auto build_tuple(std::index_sequence<Is...> is)
{
    static_assert(sizeof...(Ts) == sizeof...(Is));

    using Tuple = std::tuple<Ts...>;
    return build_tuple_impl<Tuple>(is, std::make_index_sequence<sizeof...(Ts)>{});
}

// Usage:
auto t = build_tuple<std::string, int, int>(std::index_sequence<3, 4, 5>{});

不是您不能写build_tuple<std::string, int, int, 3, 4, 5>()。序列之一应打包为单一类型。