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

C++20实现函数任意参数顺序调用并正确转发至目标函数

C++20 非暴力实现任意顺序参数调用指定顺序的bar函数
#include <concepts>

struct T1 {};

struct T2 {};

struct T3 {};

struct T4 {};

void bar(T1, T2, T3, T4) {
}

template<typename T>
concept IsT = std::same_as<T, T1> || std::same_as<T, T2> ||
              std::same_as<T, T3> || std::same_as<T, T4>;

void foo(IsT auto x1, IsT auto x2, IsT auto x3, IsT auto x4) {
    // 如何对x1、x2、x3、x4的类型排序并调用bar(x?, x?, x?, x?)?
}

int main() {
    foo(T1{},T2{},T3{},T4{}); // ok
    foo(T4{},T3{},T2{},T1{}); // ok
    foo(T3{},T2{},T1{},T4{}); // ok
    // ...
}

需求说明

用户可以以任意参数顺序调用foo函数,但最终要按正确顺序调用bar函数。

常规暴力解法是枚举24种参数排列,繁琐且易出错,以下是C++20下的非暴力解决方案:


解决方案

利用C++标准库的tuple和std::get<T>特性即可实现,无需枚举排列。std::get<T>可以从元组中直接提取指定类型的元素,只要该类型在元组中恰好出现一次(当前场景完全符合:foo的参数是T1-T4的一个排列,每个类型各出现一次)。

修改后的完整代码如下:

#include <concepts>
#include <tuple> // 需包含tuple头文件

struct T1 {};

struct T2 {};

struct T3 {};

struct T4 {};

void bar(T1, T2, T3, T4) {
}

template<typename T>
concept IsT = std::same_as<T, T1> || std::same_as<T, T2> ||
              std::same_as<T, T3> || std::same_as<T, T4>;

void foo(IsT auto x1, IsT auto x2, IsT auto x3, IsT auto x4) {
    auto args = std::make_tuple(std::move(x1), std::move(x2), std::move(x3), std::move(x4));
    bar(
        std::get<T1>(args),
        std::get<T2>(args),
        std::get<T3>(args),
        std::get<T4>(args)
    );
}

int main() {
    foo(T1{},T2{},T3{},T4{}); // ok
    foo(T4{},T3{},T2{},T1{}); // ok
    foo(T3{},T2{},T1{},T4{}); // ok
    // ...
}

原理说明

  • std::make_tuple将foo的四个参数打包成元组,元组内包含T1-T4各一个实例(顺序任意)。
  • std::get<T>(tuple)在编译期定位元组中类型为T的元素,直接提取后按bar要求的顺序传递。
  • 整个过程由编译期处理,无运行时开销,代码简洁易维护,无需处理任何排列逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 09:25:08