How to specify an overloaded function of a given signature in std :: bind?

I have an api function f_api(std::function<void(int)> func) and now I have a 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 to use Func f f (int i) to go to f_api to do the job; 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 is 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 handle this when this member function has several different subscription reload functions? Would std :: bind find me the most suitable function to call? C ++ is so complicated .....

minimum case checked:

 #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; } 

compilation 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, this is a slightly different reason why my class Func cannot be assigned, because one member field of this class cannot be assigned, so during compilation I will get a slightly different error.

+7
c ++ c ++ 11 std stdbind
source share
2 answers

You can do it in a nasty way for all overloads. 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 may find out that std::bind not all useful if you have lambdas:

 std::function<void(int)> func = [&](int i) { f(i); }; 
+15
source share

Func is a functional object. Instead of introducing a pointer to a member function, just pass the whole object to the binding and enable it when using the binding or in this case when you add it to std::function .

 Func f; std::function<void(int)> func = std::bind(f, std::placeholders::_1); 

or even better, just assign f std::function

 Func f; std::function<void(int)> func = f; 
+10
source share

All Articles