【问题标题】:boost lambda::bind return type selectionboost lambda::bind 返回类型选择
【发布时间】:2010-04-30 11:34:14
【问题描述】:

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

【问题讨论】:

    标签: boost boost-bind boost-lambda


    【解决方案1】:

    不同的返回类型是一个红鲱鱼。问题在于方法的 const 重载(即,无论相对返回类型是什么,您都会遇到同样的问题)。这是herehere 记录的问题,使用返回类型指定的形式是not the recommended solution(大部分时间都可以使用,除了某些版本的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;
    }
    

    【讨论】:

      【解决方案2】:

      对于文档

      "绑定表达式创建的 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");
      

      附:未测试

      【讨论】:

      • 您刚刚指出了真正的问题 :) 有一种方法可以覆盖 lambda::boost 中的返回类型,但它仅适用于 lambda 表达式,不适用于绑定。请参阅:参考中的 lambda::ret(e)。不幸的是,在目前的情况下它不适用......
      猜你喜欢
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多