You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对type list与value list进行成对迭代?

问题:如何将type_list与值列表打包为类型/值对并进行折叠操作?

用户定义了如下type_list模板结构体:

template <typename ...Types> struct type_list {};

希望在如下函数中实现对该类型列表与某值列表的元素对进行迭代:

template <typename ...Types, typename ...Values>
void f(type_list<Types...>, Values&&... values);

调用示例如下:

template <int i, typename T> struct P {
    static constexpr int i = i;
    using type = T;
};
f(type_list<P<1, int>, P<3, double>>{}, 11, 12);

已知两个列表长度完全一致,且类型列表中的类型与值列表中的值无关联。请问是否可以将两个列表打包为类型/值对,再进行折叠操作?


回答

当然可以实现。核心思路是借助索引序列(std::index_sequence)来将类型列表和值列表的对应元素一一配对,之后就能对配对后的元素执行折叠操作。

具体实现步骤

  1. 编写辅助处理函数
    先实现一个带索引序列的辅助函数,通过索引定位对应位置的类型和值,定义单对元素的处理逻辑:

    #include <utility>
    #include <tuple>
    #include <iostream>
    #include <typeinfo>
    
    // 处理单个类型/值对的模板函数
    template <typename T, typename V>
    void process_single(T, V&& val) {
        // 示例操作:打印P类型的参数和对应值
        if constexpr (requires { T::i; }) {
            std::cout << "P<" << T::i << ", " << typeid(typename T::type).name() << "> : " << val << "\n";
        }
    }
    
    // 带索引序列的辅助函数
    template <typename... Types, typename... Values, std::size_t... Is>
    void f_impl(type_list<Types...>, Values&&... values, std::index_sequence<Is...>) {
        // 将类型列表和值列表的对应元素配对,用折叠表达式迭代处理
        (process_single(Types{}, std::get<Is>(std::forward_as_tuple(std::forward<Values>(values)...))), ...);
    }
    
  2. 主函数转发到辅助函数
    在主函数f中生成与类型列表长度匹配的索引序列,完成参数转发:

    template <typename... Types, typename... Values>
    void f(type_list<Types...>, Values&&... values) {
        static_assert(sizeof...(Types) == sizeof...(Values), "类型列表和值列表长度必须一致");
        // 生成索引序列并调用辅助函数
        f_impl(type_list<Types...>{}, 
               std::forward<Values>(values)..., 
               std::index_sequence_for<Types...>{});
    }
    

关键说明

  • std::index_sequence_for<Types...>会自动生成长度为sizeof...(Types)的索引序列0,1,...,N-1,保证类型和值的位置一一对应。
  • std::forward_as_tuple将值列表转为元组,通过std::get<Is>取出对应位置的值,和类型列表中Types[Is]配对。
  • 折叠表达式(process_single(...), ...)会依次对每个类型/值对执行处理逻辑,实现迭代效果。

如果使用C++20及以上版本,也可以用模板lambda简化process_single的定义,省去单独写模板函数的步骤:

template <typename... Types, typename... Values, std::size_t... Is>
void f_impl(type_list<Types...>, Values&&... values, std::index_sequence<Is...>) {
    auto process = []<typename T, typename V>(T, V&& val) {
        if constexpr (requires { T::i; }) {
            std::cout << "P<" << T::i << ", " << typeid(typename T::type).name() << "> : " << val << "\n";
        }
    };
    (process(Types{}, std::get<Is>(std::forward_as_tuple(std::forward<Values>(values)...))), ...);
}

内容的提问来源于stack exchange,提问作者ridilculous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:43:10