bpw1621
bpw1621

Reputation: 3062

std::bind overload resolution

The following code works fine

#include <functional>

using namespace std;
using namespace std::placeholders;

class A
{
  int operator()( int i, int j ) { return i - j; }
};

A a;
auto aBind = bind( &A::operator(), ref(a), _2, _1 );

This does not

#include <functional>

using namespace std;
using namespace std::placeholders;

class A
{
  int operator()( int i, int j ) { return i - j; }
  int operator()( int i ) { return -i; }
};

A a;
auto aBind = bind( &A::operator(), ref(a), _2, _1 );

I have tried playing around with the syntax to try and explicitly resolve which function I want in the code that does not work without luck so far. How do I write the bind line in order to choose the call that takes the two integer arguments?

Upvotes: 29

Views: 9551

Answers (3)

lubgr
lubgr

Reputation: 38325

There are some "lift" macros available that automate passing overload sets as parameters by wrapping them into a lambda that simply forwards all parameters passed to it. One that is provided by Boost can make the code compile via

#include <boost/hof/lift.hpp>

auto aBind = bind(BOOST_HOF_LIFT(&A::operator()), ref(a), _2, _1 );

There are also proposals for making it easier to pass overload sets, see e.g. P0834, but I don't know whether this will find or found consensus.

Upvotes: 0

sigy
sigy

Reputation: 2500

If you have C++11 available you should prefer lambdas over std::bind since it usually results in code that is more readable:

auto aBind = [&a](int i, int j){ return a(i, j); };

compared to

auto aBind = std::bind(static_cast<int(A::*)(int,int)>(&A::operator()), std::ref(a), std::placeholders::_2, std::placeholders::_1);

Upvotes: 18

James McNellis
James McNellis

Reputation: 355307

You need a cast to disambiguate the overloaded function:

(int(A::*)(int,int))&A::operator()

Upvotes: 48

Related Questions