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

如何在C++20中从已有tuple生成新tuple?

问题

已有如下C代码,已创建tuple对象t1,希望对t1的每个元素分别调用f1、f2、f3函数,生成类型为std::tuple<std::string, float, int>的新tuple。请问在C20中是否有实现方式,比如使用std::tuple_cat?

代码示例:

std::string f1(int a)
{
    std::string b = "hello";
    return b;
}

float f2(std::string a)
{
    float b = 2.5f;
    return b;
}

int f3(float a)
{
    int b = 4;
    return b;
}

int main()
{
    auto t1 = std::make_tuple(1, "a", 1.5f);
    // 目标新tuple --> std::tuple<std::string, float, int>(f1(1), f2("a"), f3(1.5));
    return 0;
}
解决方案

C++20里有多种简洁的实现方式,std::tuple_cat其实并不适配这个场景(它主要用于拼接多个tuple),更合适的是用std::apply配合结构化绑定,或者借助编译期索引序列逐个处理元素。

方法1:std::apply + 结构化绑定

利用std::apply展开tuple元素为函数参数的特性,结合结构化绑定直接提取元素并调用对应函数,写法直观易懂:

#include <tuple>
#include <string>

// 保留原函数定义...

int main()
{
    auto t1 = std::make_tuple(1, "a", 1.5f);
    
    auto [a, b, c] = t1;
    auto new_tuple = std::make_tuple(f1(a), f2(b), f3(c));
    // new_tuple的类型即为std::tuple<std::string, float, int>
    
    return 0;
}

方法2:编译期索引序列(通用化方案)

如果需要适配任意长度的tuple,可借助std::make_index_sequence生成编译期索引,实现通用化的逐个元素处理:

#include <tuple>
#include <string>
#include <utility>

// 保留原函数定义...

template<typename Tuple, typename... Funcs, std::size_t... Idx>
auto apply_each_impl(const Tuple& t, std::tuple<Funcs...> funcs, std::index_sequence<Idx...>)
{
    return std::make_tuple(std::get<Idx>(funcs)(std::get<Idx>(t))...);
}

template<typename Tuple, typename... Funcs>
auto apply_each(const Tuple& t, Funcs&&... funcs)
{
    static_assert(std::tuple_size_v<Tuple> == sizeof...(Funcs), "Tuple元素数量必须与传入函数数量一致");
    return apply_each_impl(t, std::make_tuple(std::forward<Funcs>(funcs)...), 
                           std::make_index_sequence<std::tuple_size_v<Tuple>>{});
}

int main()
{
    auto t1 = std::make_tuple(1, "a", 1.5f);
    
    auto new_tuple = apply_each(t1, f1, f2, f3);
    // new_tuple类型符合要求
    
    return 0;
}

关于std::tuple_cat的说明

虽然可以用std::tuple_cat(std::make_tuple(f1(a)), std::make_tuple(f2(b)), std::make_tuple(f3(c)))生成目标tuple,但这种写法需要为每个元素创建临时tuple再拼接,冗余且没必要,远不如上面两种方法简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:20:28