I have api function f_api(std::function<void(int)> func)
and now I have my process class
class Func {
public:
void operator()(int i) {
// do some work
}
int operator()(int i, int j) {
// do some other work
}
};
and I want use Func f
f(int i) to pass to f_api to do the work; so I use std::bind
Func f;
std::function<void(int)> func = std::bind(&Func::operator(), &f, std::placeholders::_1);
f_api(func);
but HERE the problem, How can I indicate which Func::operator()()
I want to bind? I can give a member function by its name, but how can I process this when this member function do have several different signed reloading functions? Will std::bind find me the most suitable function to be called? C++ is so complicated.....
the minimal verifiable case:
#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;
}
the compiling error:
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);
^
And in my case it's a little bit different cause my class Func
cannot be assigned cause one member field of that class is not assignable, so I will get a slightly different error during the compiling time.
Function Signature A function's signature includes the function's name and the number, order and type of its formal parameters. Two overloaded functions must not have the same signature. The return value is not part of a function's signature.
std::bind is for partial function application. That is, suppose you have a function object f which takes 3 arguments: f(a,b,c); You want a new function object which only takes two arguments, defined as: g(a,b) := f(a, 4, b);
Internally, std::bind() detects that a pointer to a member function is passed and most likely turns it into a callable objects, e.g., by use std::mem_fn() with its first argument.
boost::bind is a generalization of the standard functions std::bind1st and std::bind2nd. It supports arbitrary function objects, functions, function pointers, and member function pointers, and is able to bind any argument to a specific value or route input arguments into arbitrary positions.
You can do it the nasty long way for all overloads. By casting:
using sig1 = void (Func::*)(int);
using sig2 = void (Func::*)(int, int);
std::bind(static_cast<sig1>(&Func::operator()), &f, std::placeholders::_1);
Alternatively, you could recognize the std::bind
isn't all that useful if you have lambdas:
std::function<void(int)> func = [&](int i) { f(i); };
Func is a function object. Rather than taking the member-function pointer, just hand the the entire object to bind, and let it resolve when you use the bind, or in this case when you add it to the std::function
.
Func f;
std::function<void(int)> func = std::bind(f, std::placeholders::_1);
or even better, just assign f to the std::function
Func f;
std::function<void(int)> func = f;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With