Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to indicate the overloaded function of given signature in std::bind?

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.

like image 673
Liu Weibo Avatar asked Aug 03 '17 11:08

Liu Weibo


People also ask

What would the signature in function overloading function?

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.

What does std :: bind do in C++?

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);

How does STD bind work?

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.

What is boost bind?

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.


2 Answers

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); };
like image 165
StoryTeller - Unslander Monica Avatar answered Sep 18 '22 04:09

StoryTeller - Unslander Monica


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;
like image 22
Dave S Avatar answered Sep 20 '22 04:09

Dave S