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

无需显式枚举模板参数传递泛型函数实例的方法

解决方案:借助函数类型萃取自动推导模板参数

核心思路是通过类型萃取工具从已有的FooFn别名中提取参数类型,自动生成foo模板函数的正确实例,彻底避免手动枚举参数。

步骤1:实现函数类型萃取模板

定义一个模板结构体,专门用于拆解函数类型的返回值和参数列表:

#include <functional>
#include <tuple>

using FooFn = void(int, int, int);

template<typename F>
struct function_traits;

// 特化处理普通函数类型
template<typename R, typename... Args>
struct function_traits<R(Args...)> {
    using return_type = R;
    using argument_types = std::tuple<Args...>;
    static constexpr std::size_t arg_count = sizeof...(Args);

    // 自动生成对应参数的foo实例指针
    static auto get_foo_instance() {
        return &foo<Args...>;
    }
};

template<class... Args>
void foo(Args&&... args) {
    // Do something
}

void bar(std::function<FooFn> fooFn) {
    fooFn(1, 2, 3);
}

步骤2:简洁调用自动生成的foo实例

调用时无需手动指定模板参数,直接通过function_traits从FooFn提取参数类型:

int main() {
    bar(function_traits<FooFn>::get_foo_instance());
    return 0;
}

进一步简化:封装辅助函数

如果觉得function_traits<FooFn>::get_foo_instance()略显冗长,可以封装一个更简洁的辅助函数:

template<typename Fn>
auto wrap_foo() {
    return function_traits<Fn>::get_foo_instance();
}

// 调用时更直观
bar(wrap_foo<FooFn>());

可选方案:给bar添加函数指针重载

如果允许修改bar的定义,可以新增一个接受FooFn函数指针的重载,配合辅助函数实现更直接的调用:

// 新增重载,直接处理函数指针
void bar(FooFn* fooFn) {
    fooFn(1, 2, 3);
}

// 调用方式不变
bar(wrap_foo<FooFn>());

这种方式既保留了原有的std::function版本兼容性,又支持更简洁的函数指针传递,且无论FooFn的参数数量多少,都不需要手动修改调用代码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:25:17