Я хотел бы позвонить участнику через лямбду:: связать. К сожалению, у меня есть два участника с тем же именем, но различными типами возврата. Есть ли способ помочь лямбде:: свяжите для выведения правильного типа возврата для вызова функции членства? (свяжите, хорошо работает с явным вычетом типа возврата),
#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
using namespace std;
using namespace boost;
struct A
{
A (const string & name) : m_name(name) {}
string & name () { return m_name; }
const string & name () const { return m_name; }
string m_name;
};
vector<A> av;
int main ()
{
av.push_back (A ("some name"));
// compiles fine
find_if(av.begin(), av.end(), bind<const string &>(&A::name, _1) == "some name");
// error: call of overloaded 'bind(<unresolved overloaded function type>, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >&)' is ambiguous
find_if(av.begin(), av.end(), lambda::bind(&A::name, lambda::_1) == "some name");
return 0;
}
Различные типы возврата - отвлекающий маневр. Проблема заключается в перегрузке метода const (т.е. у вас будет такая же проблема независимо от относительных типов возвращаемых значений).Эта проблема задокументирована здесь и здесь , и использование формы с указанием типа возвращаемого значения не является рекомендуемым решением (будет работать большую часть времени, за исключением некоторых версия MSVC).
Проблема в том, что получение адреса перегруженной функции-члена (либо const, либо перегруженный параметр) неоднозначно, поэтому требуется некоторая дополнительная информация.
Решение состоит в том, чтобы преобразовать указатель функции, который позволяет компилятору точно знать, какая из перегруженных функций вам нужна. Самый простой способ сделать это, который я нашел, - это определить типы указателя функции, поскольку в противном случае строки получат немного противно. Вот пример вашего кода (компилирует чистый gcc 4.3.4):
#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
using namespace std;
using namespace boost;
struct A
{
A (const string & name) : m_name(name) {}
string & name () { return m_name; }
const string & name () const { return m_name; }
string m_name;
};
vector<A> av;
//function pointer for non-const version
typedef string& (A::*NameFuncType)(void);
//function pointer for const version
typedef const string& (A::*NameConstFuncType)(void) const;
int main ()
{
av.push_back (A ("some name"));
//'correct' way to call const version w/ boost::bind
find_if(av.begin(), av.end(),
bind(static_cast<NameConstFuncType>(&A::name), _1) == "some name"
);
//call for non-const version w/ boost::lambda::bind
find_if(av.begin(), av.end(),
lambda::bind(static_cast<NameFuncType>(&A::name), lambda::_1) == "some name"
);
return 0;
}
Для документации
"Возвращаемый тип лямбда-функтора, созданного выражением bind, может быть задан как явно указанный параметр шаблона, как в следующем примере:
bind(target-function, bind-argument-list)"
Так что просто сделайте то же самое, что вы делали с boost:bind.
find_if(av.begin(), av.end(), lambda::bind<const string &>(&A::name, lambda::_1) == "some name");
P.S. не проверено