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

在index_sequence场景下实现多元组同步索引的函数调用展开

问题分析

需求是将指定函数同步应用到多个元组的同索引元素:先处理所有元组的第0个元素,再处理第1个,以此类推。现有模板代码的核心问题在于折叠表达式的展开逻辑错误:

  • std::get<Is>(tups)仅能获取单个元组的Is索引元素,无法覆盖所有元组
  • std::get<Is>(tups)...会同时展开索引序列和元组列表,导致每个索引对应所有元组的元素,不符合同步索引的要求
修复后的实现

通过嵌套折叠表达式实现:对每个索引Is,先展开所有元组的std::get<Is>(tup)作为函数的前置参数,再拼接额外传入的参数,最后用逗号表达式依次执行每个索引对应的函数调用。

#include <tuple>
#include <utility>
#include <type_traits>

// 核心实现:接收索引序列、元组列表、额外参数
template <auto Func, class... Tuples, class... Fargs, std::size_t... Is>
auto applyInLockStep(std::index_sequence<Is...>,
                     Tuples &&... tups,
                     Fargs &&...args) {
    // 关键:对每个Is,先展开所有元组的get<Is>,再传递给Func,最后追加args
    return (Func( (std::get<Is>(std::forward<Tuples>(tups)))..., std::forward<Fargs>(args)... ), ...);
}

// 外层封装:自动推导索引序列,无需用户手动生成
template <auto Func, class FirstTuple, class... RestTuples, class... Fargs>
auto applyInLockStep(FirstTuple &&first_tup, RestTuples &&... rest_tups, Fargs &&... args) {
    constexpr auto tuple_size = std::tuple_size_v<std::decay_t<FirstTuple>>;
    // 静态断言:确保所有元组大小一致
    static_assert(((std::tuple_size_v<std::decay_t<RestTuples>> == tuple_size) && ...), "All tuples must have identical size");
    return applyInLockStep<Func>(
        std::make_index_sequence<tuple_size>{},
        std::forward<FirstTuple>(first_tup),
        std::forward<RestTuples>(rest_tups)...,
        std::forward<Fargs>(args)...
    );
}
调用示例(简化版)

原调用代码无需修改,或者使用外层封装的简化调用:

using Tup = std::tuple<float, float, float>;
Tup t1, t2;

constexpr auto f = [&]<class T1E, class T2E>(T1E && t1E,
                                   T2E && t2E,
                                   float t) {
   return myf(std::forward<T1E>(t1E), std::forward<T2E>(t2E), t);
};

// 简化调用:无需手动传递index_sequence
applyInLockStep<f>(t1, t2, 1.0f);
展开效果验证

代码会被展开为预期的形式:

Func(std::get<0>(t1), std::get<0>(t2), 1.0f),
Func(std::get<1>(t1), std::get<1>(t2), 1.0f),
Func(std::get<2>(t1), std::get<2>(t2), 1.0f)
注意事项
  • 所有传入的元组必须大小一致,否则静态断言会触发编译错误
  • 函数Func需要能接受对应数量的元组元素类型,加上额外传入的参数类型
  • 完美转发确保了元组元素和额外参数的左值/右值类别被正确保留

内容的提问来源于stack exchange,提问作者Germán Diago

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 19:25:14