Разрешение перегрузки std::bind
Следующий код работает нормально
#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 );
Это не
#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 );
Я попытался поиграться с синтаксисом, чтобы попытаться явно определить, какую функцию я хочу в коде, который до сих пор не работает без удачи. Как мне написать строку связывания, чтобы выбрать вызов, который принимает два целочисленных аргумента?
2 ответа
Вам нужен приведение для устранения неоднозначности перегруженной функции:
(int(A::*)(int,int))&A::operator()
Если у вас есть C++11, вы должны предпочесть лямбды std::bind
поскольку обычно это приводит к тому, что код становится более читабельным:
auto aBind = [&a](int i, int j){ return a(i, j); };
по сравнению с
auto aBind = std::bind(static_cast<int(A::*)(int,int)>(&A::operator()), std::ref(a), std::placeholders::_2, std::placeholders::_1);
Доступны некоторые макросы "lift", которые автоматизируют передачу наборов перегрузки в качестве параметров, помещая их в лямбду, которая просто пересылает все передаваемые ему параметры. Тот, который предоставляется Boost, может заставить код компилироваться через
#include <boost/hof/lift.hpp>
auto aBind = bind(BOOST_HOF_LIFT(&A::operator()), ref(a), _2, _1 );
Существуют также предложения по упрощению прохождения наборов перегрузки, см., Например, P0834, но я не знаю, найдет ли это или нашел консенсус.