boost lambda::bind 返回类型选择

发布于 2024-08-30 21:14:14 字数 1043 浏览 2 评论 0原文

我想通过 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;
}

I would like to call a member through lambda::bind. Unfortunately I have got two members with the same name but different return types.
Is there a way to help the lambda::bind to deduce the right return type for a member function call? (bind works fine with explicit return type deduction)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑忘罢 2024-09-06 21:14:14

不同的返回类型是一个转移注意力的话题。问题在于方法的 const 重载(即,无论相对返回类型是什么,您都会遇到相同的问题)。这个问题记录在此处和< a href="http://www.boost.org/doc/libs/1_43_0/doc/html/lambda/le_in_details.html#lambda.function_pointers_as_targets" rel="nofollow noreferrer">此处,并使用返回类型指定的形式不是推荐的解决方案(大多数情况下都可以工作,除了某些版本的 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;
}

The different return types is a red herring. The issue is with const overloading of method (i.e. you would have the same problem no matter what the relative return types are). This is problem is documented here and here, and using the return type-specified form is not the recommended solution (will work most of the time, except some version of MSVC).

The problem is that taking the address of an overloaded member function (either const overloaded or parameter overloaded) is ambiguous, so some extra information is required.

The solution is to cast the function pointer, which lets the compiler know exactly which of the overloaded functions you want, The cleanest way to do this I've found is to typedef the function pointer types, since otherwise the lines get a bit nasty. Here's an example with your code (compiles clean 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;
}
打小就很酷 2024-09-06 21:14:14

对于文档

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

bind(target-function, bind-argument-list)”

所以只需执行相同的操作你用 boost:bind 做的事情。

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

PS未测试

For the documentation

"The return type of the lambda functor created by the bind expression can be given as an explicitly specified template parameter, as in the following example:

bind(target-function, bind-argument-list)"

So just do the same thing you did with boost:bind.

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

P.S. not tested

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文