лямбда повышения:: свяжите выбор типа возврата

Я хотел бы позвонить участнику через лямбду:: связать. К сожалению, у меня есть два участника с тем же именем, но различными типами возврата. Есть ли способ помочь лямбде:: свяжите для выведения правильного типа возврата для вызова функции членства? (свяжите, хорошо работает с явным вычетом типа возврата),

#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;
}
1
задан psaghelyi 30 April 2010 в 12:56
поделиться

2 ответа

Различные типы возврата - отвлекающий маневр. Проблема заключается в перегрузке метода 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;
}
1
ответ дан 3 September 2019 в 00:56
поделиться

Для документации

"Возвращаемый тип лямбда-функтора, созданного выражением 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. не проверено

1
ответ дан 3 September 2019 в 00:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: