2010-04-30 163 views
1

我想通过lambda :: bind调用成员。不幸的是,我有两个具有相同名称但返回类型不同的成员。 有没有办法来帮助lambda :: bind推断成员函数调用的正确返回类型? (结合正常工作与明确的返回类型扣)boost 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; 
} 

回答

1

不同的退货类型是红鲱鱼。问题在于方法的const重载(即无论相对返回类型是什么,你都会遇到同样的问题)。这是问题记录herehere,并使用返回类型指定的形式是not the recommended solution(大多数情况下,除某些版本的MSVC以外)。

问题是,重载成员函数(常量重载或参数重载)的地址是不明确的,所以需要一些额外的信息。

解决方案是转换函数指针,它可以让编译器确切地知道你想要的是哪个重载函数。我找到的最简洁的方法是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; 
} 
1

有关文档

“由bind表达式创建的lambda仿函数的返回类型可以被给定为一个显式指定的模板参数,如在下面的例子:

绑定(目标功能,绑定参数列表)”

所以只要你有增强做同样的事情:绑定。

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

P.S.未经测试

+0

您刚才指出了真正的问题:) 有一种方法来覆盖拉姆达的返回类型::提升,但它仅适用为lambda表达式不为绑定。参见:lambda :: ret (e)。不幸的是,在目前的情况下,它不适用... – psaghelyi 2010-04-30 21:27:50