C++11中std::function与模板参数的使用及代码报错修复
问题分析与修复方案
首先来说说你代码报错的核心原因:
当你调用apply("abc", process_s)时,编译器需要推导模板函数apply的模板参数T,但这里遇到了推导障碍。你的apply函数第二个参数是const function<int(T)>&,而你传入的process_s是一个类型为int(*)(const S&)的函数指针——编译器没办法从这个函数指针反向推导出T的具体类型,因为std::function是一个通用包装器,它可以兼容多种可调用对象类型,编译器没法确定你期望的T是S还是const S&,所以直接报了"找不到匹配函数"的错误。
接下来给你几种修复方案,按需选择:
方案1:显式指定模板参数
最简单的办法就是在调用apply时,直接告诉编译器T的类型:
#include <iostream> #include <functional> using namespace std; template <typename T> int apply(string x, const function<int(T)>& fn) { T t = { x }; return fn(t); } struct S { string data; }; int process_s(const S& s) { return s.data.size(); } int main() { // 显式指定T为const S&,让编译器明确推导方向 cout << apply<const S&>("abc", process_s); }
方案2:让模板直接推导可调用对象类型(更推荐)
其实没必要把参数限制成std::function,直接让模板推导可调用对象的类型,代码会更灵活,还能避免std::function的额外开销:
#include <iostream> #include <functional> #include <type_traits> using namespace std; // 模板参数直接推导可调用对象的类型 template <typename Fn> int apply(string x, Fn&& fn) { // 通过invoke_result获取可调用对象的参数类型 using T = typename std::invoke_result_t<Fn, const S&>::argument_type; T t = { x }; return fn(t); } // 如果你的场景固定只处理S类型,还可以更简化: // template <typename Fn> // int apply(string x, Fn&& fn) { // S t = { x }; // return fn(t); // } struct S { string data; }; int process_s(const S& s) { return s.data.size(); } int main() { cout << apply("abc", process_s); }
这种方式不仅解决了推导问题,还能兼容lambda、成员函数指针等更多可调用对象,适用性更广。
方案3:提前把函数指针包装成std::function
你也可以先把process_s转换成对应的std::function类型再传入,这样编译器就能自动推导T了:
int main() { function<int(const S&)> fn = process_s; cout << apply("abc", fn); }
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

