使用std::bind绑定含非默认拷贝构造函数类参数的成员函数报错
关于std::bind绑定带参数成员函数的编译错误问题
问题描述
尝试用std::bind绑定带单个参数的成员函数,初始代码编译正常,但给message类添加自定义拷贝构造函数后出现编译错误。
初始代码
// tester.hpp #include <functional> class message { public: message() { } //message(message &msg){value = msg.value;} // 取消注释此行会导致错误 int value = 0; }; class messageHandler { public: messageHandler() { handleIntFn = std::bind(&messageHandler::handleInt, this, std::placeholders::_1); handleMessageFn = std::bind(&messageHandler::handleMsg, this, std::placeholders::_1); } private: bool handleInt(int value) { return value == 0; } bool handleMsg(message msg) { return msg.value == 0; } std::function<bool(int)> handleIntFn; std::function<bool(message)> handleMessageFn; };
编译错误信息
/home/tester.hpp:19:92: error: no match for 'operator=' (operand types are 'std::function<bool(message)>' and 'std::_Bind_helper<false, bool (messageHandler::*)(message), messageHandler*, const std::_Placeholder<1>&>::type') 19 | handleMessageFn = std::bind(&messageHandler::handleMsg, this, std::placeholders::_1); | ^ In file included from /usr/include/newlib/c++/10.3.1/functional:59, from /home/tester.hpp:1, from /home/tester.cpp:1: /usr/include/newlib/c++/10.3.1/bits/std_function.h:396:7: note: candidate: 'std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = bool; _ArgTypes = {message}]' 396 | operator=(const function& __x) | ^~~~~~~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:396:33: note: no known conversion for argument 1 from 'std::_Bind_helper<false, bool (messageHandler::*)(message), messageHandler*, const std::_Placeholder<1>&>::type' to 'const std::function<bool(message)>&' 396 | operator=(const function& __x) | ~~~~~~~~~~~~~~~~^~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:414:7: note: candidate: 'std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::function<_Res(_ArgTypes ...)>&&) [with _Res = bool; _ArgTypes = {message}]' 414 | operator=(function&& __x) noexcept | ^~~~~~~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:414:28: note: no known conversion for argument 1 from 'std::_Bind_helper<false, bool (messageHandler::*)(message), messageHandler*, const std::_Placeholder<1>&>::type' to 'std::function<bool(message)>&&' 414 | operator=(function&& __x) noexcept | ~~~~~~~~~~~^~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:428:7: note: candidate: 'std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::nullptr_t) [with _Res = bool; _ArgTypes = {message}; std::nullptr_t = std::nullptr_t]' 428 | operator=(nullptr_t) noexcept | ^~~~~~~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:428:17: note: no known conversion for argument 1 from 'std::_Bind_helper<false, bool (messageHandler::*)(message), messageHandler*, const std::_Placeholder<1>&>::type' to 'std::nullptr_t' 428 | operator=(nullptr_t) noexcept | ^~~~~~~~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:457:2: note: candidate: 'template<class _Functor> std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<typename std::decay<_Functor>::type>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = _Functor; _Res = bool; _ArgTypes = {message}]' 457 | operator=(_Functor&& __f) | ^~~~~~~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:457:2: note: template argument deduction/substitution failed: /usr/include/newlib/c++/10.3.1/bits/std_function.h: In substitution of 'template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond::value, _Tp>::type [with _Cond = std::function<bool(message)>::_Callable<std::_Bind<bool (messageHandler::*(messageHandler*, std::_Placeholder<1>))(message)>, std::__invoke_result<std::_Bind<bool (messageHandler::*(messageHandler*, std::_Placeholder<1>))(message)&, message> >; _Tp = std::function<bool(message)>&; _Res = bool; _ArgTypes = {message}]': /usr/include/newlib/c++/10.3.1/bits/std_function.h:457:2: required by substitution of 'template<class _Functor> std::function<bool(message)>::_Requires<std::function<bool(message)>::_Callable<typename std::decay<_Tp>::type, std::__invoke_result<typename std::decay<_Tp>::type&, message> >, std::function<bool(message)>&> std::function<bool(message)>::operator=<(_Functor&&) [with _Functor = std::_Bind<bool (messageHandler::*(messageHandler*, std::_Placeholder<1>))(message)>]' /home/tester.hpp:19:92: required from here /usr/include/newlib/c++/10.3.1/bits/std_function.h:319:8: error: no type named 'type' in 'struct std::enable_if<false, std::function<bool(message)>&>' 319 | using _Requires = typename enable_if<_Cond::value, _Tp>::type; | ^~~~~~~~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:466:2: note: candidate: 'template<class _Functor> std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(std::reference_wrapper<_Functor>) [with _Functor = _Functor; _Res = bool; _ArgTypes = {message}]' 466 | operator=(reference_wrapper<_Functor> __f) noexcept | ^~~~~~~~ /usr/include/newlib/c++/10.3.1/bits/std_function.h:466:2: note: template argument deduction/substitution failed: In file included from /home/tester.cpp:1: /home/tester.hpp:19:92: note: 'std::_Bind<bool (messageHandler::*(messageHandler*, std::_Placeholder<1>))(message)>' is not derived from 'std::reference_wrapper<_Tp>' 19 | handleMessageFn = std::bind(&messageHandler::handleMsg, this, std::placeholders::_1); |
疑问:std::bind是否依赖默认拷贝构造函数?为何无法使用自定义拷贝构造函数?预期它应该支持带有拷贝构造函数的类。
解答
问题根源
不是std::bind依赖默认拷贝构造函数,而是自定义拷贝构造函数的参数为非常量引用,导致类型兼容性冲突:
- 当定义
message(message &msg)时,编译器会自动禁用默认的const message&版本拷贝构造函数。 handleMsg的参数是值传递message msg,调用时需要从临时对象(右值)构造参数,但右值无法绑定到非常量引用的拷贝构造函数参数上。std::function在验证std::bind生成的对象是否可匹配bool(message)签名时,发现无法完成参数构造,因此触发编译错误。
解决方法
将自定义拷贝构造函数的参数改为常量引用即可:
message(const message &msg){value = msg.value;}
补充说明
- 自定义拷贝构造函数使用
const引用是C++的标准实践,既能兼容右值临时对象,也符合常量正确性原则。 - 若确实需要非常量引用的拷贝构造函数(极少场景),可将
handleMsg的参数改为message&,但这会限制函数只能接受左值,灵活性较差。
内容的提问来源于stack exchange,提问作者Kiwewi
相关产品推荐
相关产品推荐

