C++如何优雅批量拼接两个同类型std::tuple的对应位置元素
实现方案
要避免逐位置硬编码std::get<N>的冗余写法,核心是利用编译期索引展开机制遍历tuple:std::index_sequence可以生成和tuple等长的编译期常量索引序列,配合C++17折叠表达式就能批量执行每个位置的vector拼接逻辑,适配任意长度的同类型tuple。
C++17 通用实现
代码分为两层,对外接口自动推导tuple长度生成索引序列,内部实现通过索引展开执行每个位置的插入操作:
#include <tuple> #include <vector> #include <cstddef> #include <utility> template<typename Tuple, std::size_t... Idx> void concat_impl(Tuple& dest, const Tuple& src, std::index_sequence<Idx...>) { // 折叠表达式展开,逐个执行对应位置vector的区间插入 (std::get<Idx>(dest).insert( std::get<Idx>(dest).end(), std::get<Idx>(src).cbegin(), std::get<Idx>(src).cend() ), ...); } template<typename... VecTypes> void concat_tuple_vectors(std::tuple<VecTypes...>& dest, const std::tuple<VecTypes...>& src) { concat_impl(dest, src, std::make_index_sequence<sizeof...(VecTypes)>{}); }
调用方式
直接传入两个同类型tuple即可,不需要关心tuple内元素个数:
std::tuple<std::vector<int>, std::vector<int>> t1, t2; // 初始化t1、t2逻辑略 concat_tuple_vectors(t1, t2); // 执行后t1的第N个vector将包含原t1、t2第N个vector的所有元素
C++20 简化版本
C++20支持带模板参数列表的lambda,不需要单独编写内部impl函数,代码更简洁:
#include <tuple> #include <vector> #include <cstddef> #include <utility> template<typename... VecTypes> void concat_tuple_vectors(std::tuple<VecTypes...>& dest, const std::tuple<VecTypes...>& src) { [&]<std::size_t... Idx>(std::index_sequence<Idx...>) { (std::get<Idx>(dest).insert( std::get<Idx>(dest).end(), std::get<Idx>(src).cbegin(), std::get<Idx>(src).cend() ), ...); }(std::make_index_sequence<sizeof...(VecTypes)>{}); }
注意事项
- 该实现直接修改输入的dest tuple,符合允许修改原对象的要求,无额外tuple拷贝开销,每个vector的插入逻辑和手写
insert完全一致,没有性能损耗。 - 实现不局限于
std::vector<int>,只要两个tuple类型完全匹配,对应位置容器支持区间插入接口(如std::string、std::deque等)均可使用。 std::apply仅支持展开单个tuple的元素作为函数参数,直接调用无法同时处理两个tuple的对应位置元素,若要基于std::apply实现需要手动绑定两个tuple的对应元素为参数组,写法冗余易出错,不如std::index_sequence的实现直观。
内容的提问来源于stack exchange,提问作者wittn
相关产品推荐
相关产品推荐

