c++ - 如何将 Parameter Pack 转换为 std::tuple 之外的其他内容?

标签 c++ template-meta-programming boost-mpl

通过一个例子可以更好地解释:

template <typename T1, typename T2>
struct OnePair
{
    using TupleOfArgs = std::tuple<T1, T2>;
    using TupleOfPairs = std::tuple<std::pair<T1, T2>>;
};

template <typename T1, typename T2, typename T3, typename T4>
struct TwoPairs
{
    using TupleOfArgs = std::tuple<T1, T2, T3, T4>;
    using TupleOfPairs = std::tuple<std::pair<T1, T2>, std::pair<T3, T4>>;
};

template <typename... Args>
struct NPairs
{
    using TupleOfArgs = std::tuple<Args...>;
//  using TupleOfPairs = ???
};

OnePair 定义一个具有一对的元组。 TwoPairs 定义了一个包含两对的元组。

如何在 NPairs 中定义 TupleOfPairs,以便将参数包转换为 std::tuple 对?

是否可以使用 std 库来实现这一点?也许用 boost::mpl ?

两个答案,都很好。 @chris 使用迭代方法,而 @aschepler 使用递归解决方案。 就我个人而言,我发现递归解决方案更容易遵循。

最佳答案

您可以使用熟悉的索引序列技巧,但大小减半 ( live example ):

static constexpr auto get_tuple() {
    constexpr auto N = sizeof...(Args);
    static_assert(N%2 == 0);

    using ArgsTuple = std::tuple<Args...>;
    auto impl = []<std::size_t... Is>(std::index_sequence<Is...>) {
        return std::tuple<
            // Is goes from 0 to N/2, representing Ith pair
            std::pair<std::tuple_element_t<Is*2, ArgsTuple>, std::tuple_element_t<Is*2 + 1, ArgsTuple>>...
        >{};
    };

    return impl(std::make_index_sequence<N/2>{});
}

using TupleOfArgs = decltype(get_tuple());

如果您没有 C++20,则必须将 lambda 扩展为函数,而不是能够使用良好的内联索引序列扩展,但核心仍然可以运行。使用类型列表而不是 std::tuple 可能会更干净一些,但它是可行的。

关于c++ - 如何将 Parameter Pack 转换为 std::tuple 之外的其他内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61335122/

相关文章:

c++ - 寻找最低值(value)。功能。错误 : Thread 1: EXC_BAD_ACCESS (Code =1, 地址 = 0x7fff5fc89000)

c++ - 如何创建具有指定数量的元素(相同类型)的 boost::tuple?

c++ - 将 boost::mpl::find_if 与自定义谓词一起使用

c++ - 什么是 std::identity 以及它是如何使用的?

c++ - 给定一个任意容器,推导出一个相关类型的容器类型

c++ - 根据可变参数模板对类型进行分类

c++ - 用于识别模板类中的类的元函数出现问题

c++ - 调试断言失败 : map/set iterator not dereferencable

c++ - 关于在 C++ 中返回 const 引用

c++ - 立方体的法线似乎指向内部