使用std::bind初始化std::function报构造函数不匹配错误怎么办
问题描述
定义接收函数f1作为入参的类,类内成员f2是固定f1部分参数得到的新函数。使用std::bind初始化f2时抛出编译错误:
error: no matching function for call to ‘std::function<double(const double&)>::function()’
原始问题代码
类实现
template <typename Function> class B{ public: B(const Function& func_, const double& b): _f1{func_}, _b{b}, _f2{std::bind(&func_, _b, std::placeholders::_1)} {} public: Function _f1; double _b; std::function<double(const double&)> _f2; };
调用代码
double function2(const double& a, const double& b){ return a+b; } using FunctionB = std::function<double(const double&, const double&)>; int main(){ B<FunctionB> b1(function, 2.5); return 0; }
错误原因
代码有三处问题直接导致编译失败/逻辑错误:
std::bind第一个参数错误传了构造函数形参func_的地址&func_:func_是构造函数栈上的局部引用形参,取地址得到的是const Function*类型的栈指针,既不能作为可调用对象直接被bind适配(指向std::function实例的指针没有默认operator(),导致bind生成的对象签名完全不匹配std::function<double(const double&)>的要求,重载决议失败时编译器会列出所有候选构造函数,包含无参默认构造,最终抛出你看到的编译错误),还会在构造函数结束后成为悬空指针。- 绑定参数顺序错误:目标函数
f1的参数顺序为(a, b),需求是固定第二个参数b,后续调用f2时传入第一个参数a,但原代码把_b放在绑定参数的第一位、占位符放在第二位,实际调用时会把固定值传给a,传入的动态参数传给b,逻辑完全颠倒。 - 调用代码笔误:
main函数中构造B实例时传入的function未定义,实际定义的函数名为function2。
额外注意:类成员初始化顺序严格和成员声明顺序一致,和初始化列表书写顺序无关。原类成员声明顺序为_f1 -> _b -> _f2,初始化_f2时前两个成员已经完成初始化,可以安全引用。
修复方案
- 去掉取地址符,
bind第一个参数使用类成员_f1(已经通过构造函数形参完成拷贝初始化,生命周期和类实例一致)。 - 调整绑定参数顺序,将占位符
std::placeholders::_1放在第一个参数位匹配a,_b放在第二个参数位固定b。如果需要f2实时读取类成员_b的最新值而非绑定时的拷贝值,可以用std::ref(_b)包装_b实现引用捕获。 - 修正调用代码的函数名笔误,补充必要头文件引用。
修复后的完整代码:
#include <functional> template <typename Function> class B{ public: B(const Function& func_, const double& b): _f1{func_}, _b{b}, // 需要实时读取_b最新值时,改为std::bind(_f1, std::placeholders::_1, std::ref(_b)) _f2{std::bind(_f1, std::placeholders::_1, _b)} {} public: Function _f1; double _b; std::function<double(const double&)> _f2; }; double function2(const double& a, const double& b){ return a+b; } using FunctionB = std::function<double(const double&, const double&)>; int main(){ B<FunctionB> b1(function2, 2.5); // 测试调用:b1._f2(1) 会返回 3.5 return 0; }
内容的提问来源于stack exchange,提问作者lucasyu
相关产品推荐
相关产品推荐

