1

我想通过 lambda::bind 调用成员。不幸的是,我有两个同名但返回类型不同的成员。有没有办法帮助 lambda::bind 推断成员函数调用的正确返回类型?(绑定适用于显式返回类型推导)

#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;
}
4

2 回答 2

1

对于文档

“绑定表达式创建的 lambda 仿函数的返回类型可以作为显式指定的模板参数给出,如下例所示:

绑定(目标函数,绑定参数列表)“

因此,只需执行与 boost:bind 相同的操作即可。

  find_if(av.begin(), av.end(), lambda::bind<const string &>(&A::name, lambda::_1) == "some name");

PS 未测试

于 2010-04-30T15:43:52.047 回答
1

不同的返回类型是一个红鲱鱼。问题在于方法的 const 重载(即,无论相对返回类型是什么,您都会遇到同样的问题)。此处此处记录了此问题,并且不推荐使用指定返回类型的形式(大多数情况下都可以使用,某些版本的 MSVC 除外)。

问题是获取重载成员函数(const 重载或参数重载)的地址是不明确的,因此需要一些额外的信息。

解决方案是强制转换函数指针,它可以让编译器确切地知道你想要哪个重载函数,我发现的最干净的方法是对函数指针类型进行 typedef,否则这些行会有点讨厌。这是您的代码示例(编译干净的 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;
}
于 2010-05-19T01:11:06.673 回答