【发布时间】:2018-01-10 22:43:55
【问题描述】:
我有 api 函数 f_api(std::function<void(int)> func) 现在我有我的进程类
class Func {
public:
void operator()(int i) {
// do some work
}
int operator()(int i, int j) {
// do some other work
}
};
我想使用Func f f(int i) 传递给 f_api 来完成这项工作;所以我使用 std::bind
Func f;
std::function<void(int)> func = std::bind(&Func::operator(), &f, std::placeholders::_1);
f_api(func);
但是这里的问题是,我怎样才能指出我想绑定哪个Func::operator()()?我可以通过它的名字给一个成员函数,但是当这个成员函数确实有几个不同的签名重新加载函数时,我该如何处理呢? std::bind 会为我找到最合适的函数吗? C++好复杂.....
最小可验证案例:
#include <iostream>
#include <functional>
using namespace std;
class Func {
public:
void operator()(int i) {
// do some work
cout << "i is: " << i << endl;
}
int operator()(int i, int j) {
// do some other work
}
};
void f_api(function<void(int)> f) {
f(3);
}
int main () {
Func f;
std::function<void(int)> func = std::bind(&Func::operator(), &f, std::placeholders::_1);
f_api(func);
return 0;
}
编译错误:
a.cpp: In function ‘int main()’:
a.cpp:23:91: error: no matching function for call to ‘bind(<unresolved overloaded function type>, Func*, const std::_Placeholder<1>&)’
std::function<void(int)> func = std::bind(&Func::operator(), &f, std::placeholders::_1);
^
a.cpp:23:91: note: candidates are:
In file included from a.cpp:2:0:
/usr/include/c++/4.8/functional:1655:5: note: template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__or_<std::is_integral<typename std::decay<_Tp>::type>, std::is_enum<typename std::decay<_Tp>::type> >::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...)
bind(_Func&& __f, _BoundArgs&&... __args)
^
/usr/include/c++/4.8/functional:1655:5: note: template argument deduction/substitution failed:
a.cpp:23:91: note: couldn't deduce template parameter ‘_Func’
std::function<void(int)> func = std::bind(&Func::operator(), &f, std::placeholders::_1);
^
In file included from a.cpp:2:0:
/usr/include/c++/4.8/functional:1682:5: note: template<class _Result, class _Func, class ... _BoundArgs> typename std::_Bindres_helper<_Result, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...)
bind(_Func&& __f, _BoundArgs&&... __args)
^
/usr/include/c++/4.8/functional:1682:5: note: template argument deduction/substitution failed:
a.cpp:23:91: note: couldn't deduce template parameter ‘_Result’
std::function<void(int)> func = std::bind(&Func::operator(), &f, std::placeholders::_1);
^
在我的情况下,它有点不同,因为我的 class Func 无法分配,因为该类的一个成员字段不可分配,所以在编译期间我会得到一个稍微不同的错误。
【问题讨论】:
-
您尝试过吗?您是否遇到任何错误,或者它是否按预期工作?
-
我建议你忘记 std::bind 甚至存在。几乎总是 lambda 更容易理解。
-
是的,我有。当我做
f_api(func)。它向我显示了有关函数对象分配不兼容的错误 -
@kay 如果他仅限于 C++11 或 0x,那么在某些情况下他必须优先使用 lambda。加上一些编译器的实现会提示绑定使用。例如。 2012 年之后的任何 Microsoft 编译器。
-
@LiuWeibo - 你也不能轻易地将指针传递给
bind的结果。此外,可以将无捕获 lambda 转换为常规函数指针。std::bind的结果不能保证以 IIRC 的这种方式进行转换。