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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:04:21