无需显式枚举模板参数传递泛型函数实例的方法
解决方案:借助函数类型萃取自动推导模板参数
核心思路是通过类型萃取工具从已有的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
相关产品推荐
相关产品推荐

