我想通过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;
}
答案 0 :(得分:1)
文档
“绑定表达式创建的lambda仿函数的返回类型可以作为显式指定的模板参数给出,如下例所示:
bind(target-function,bind-argument-list)“
所以就像你用boost做的一样:绑定。
find_if(av.begin(), av.end(), lambda::bind<const string &>(&A::name, lambda::_1) == "some name");
P.S。未经测试
答案 1 :(得分:1)
不同的回报类型是红鲱鱼。问题是const重载方法(即无论相对返回类型是什么,你都会遇到同样的问题)。这是问题记录here和here,并且使用返回类型指定的表单是not the recommended solution(除了某些版本的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;
}