C++中如何将模板函数作为模板参数传入另一个函数
实现方案
你想要的效果没法直接把函数模板作为参数传入,因为C++的模板参数不支持直接接收函数模板作为输入,只有类模板和别名模板可以作为模板模板参数传入。这里给三种常用的落地实现:
方案1:用模板仿函数包装操作(兼容性最好,支持C++11及以上版本)
你可以把原来的doSomething逻辑封装成一个带模板operator()的仿函数类型,之后把这个仿函数类型作为模板参数传给doMore即可:
// 包装doSomething逻辑的仿函数 struct DoSomethingOp { template <typename T> T operator()(T x, T y) const { T result = /* 原doSomething的具体操作 */; return result; } }; // doMore实现,第三个模板参数接收仿函数类型 template <typename T, typename V, typename Op> T doMore(V v) { Op op; // 这里要加template关键字告诉编译器operator()是模板 T result = op.template operator()<V>(v, 0); return result; } // 调用示例 int main() { // 传入仿函数类型DoSomethingOp作为模板参数 auto res = doMore<int, double, DoSomethingOp>(3.14); return 0; }
如果你不想修改原有doSomething函数模板的实现,也可以单独写一个仿函数调用原函数即可:
struct DoSomethingOp { template <typename T> T operator()(T x, T y) const { return doSomething<T>(x, y); } };
方案2:C++20 模板lambda简化写法
如果你用C++20及以上版本,可以直接用模板lambda包装操作,代码更简洁:
// 直接用模板lambda包装doSomething constexpr auto do_something_lambda = []<typename T>(T x, T y) -> T { return doSomething<T>(x, y); }; // doMore用auto非类型模板参数接收lambda template <typename T, typename V, auto Op> T doMore(V v) { T result = Op.template operator()<V>(v, 0); return result; } // 调用示例 int main() { auto res = doMore<int, double, do_something_lambda>(3.14); return 0; }
方案3:模板标签包装函数模板
如果你不想引入仿函数实例,也可以用模板标签类关联你要调用的函数模板,用模板模板参数接收:
// 定义标签模板,绑定doSomething template <typename T> struct DoSomethingTag { static T call(T x, T y) { return doSomething<T>(x, y); } }; // doMore的第三个参数是模板模板参数,接收标签模板 template <typename T, typename V, template <typename> typename Tag> T doMore(V v) { T result = Tag<V>::call(v, 0); return result; } // 调用示例 int main() { auto res = doMore<int, double, DoSomethingTag>(3.14); return 0; }
内容的提问来源于stack exchange,提问作者Polynomial length of study
相关产品推荐
相关产品推荐

