我有一个像这样的简单类:
class A
{
public:
void f(const int& n)
{
std::cout<<"A::f()" << n <<"\n";
}
};
我试图像这样使用它:
std::vector<A> vec;
A a;
vec.push_back(a);
std::for_each(vec.begin(), vec.end(), std::bind2nd(std::mem_fun_ref(&A::f), 9));
但是当我编译代码时,我在函数头文件中的某处出现了以下错误:
错误C2529:'_ Right':引用 参考是非法的
如果我删除参数f()中的引用,它编译得很好。我该如何解决这个问题?我不想删除引用,因为在我的实际代码中复制对象是非常昂贵的。另外,我没有使用提升。
答案 0 :(得分:5)
抱歉,你不能轻易做到这一点。只考虑std::bind1st
和std::bind2nd
未涵盖的案例之一(有点像3参数函数等)。 Boost会有所帮助 - boost::bind
透明地支持引用,还有boost::ref
。
如果您的实现支持TR1 - 最新的g ++版本和VC ++ 2008 SP1都可以 - 那么您可以使用std::tr1::bind
,它与boost::bind
大部分相同,但标准化。
答案 1 :(得分:2)
我不相信你可以将参数绑定到接受引用的方法。 (不是在STL中,我认为升级版本可能会让你这样做,但我不确定)
你需要自己动手。
struct CallF
{
CallF(int const& data): m_data(data) {}
void operator()(A& val) const
{
val.f(m_data);
}
int const& m_data;
};
像这样使用:
std::for_each(vec.begin(), vec.end(), CallF(9));
答案 2 :(得分:1)
我被同样的问题困扰了。如果你研究C ++标准,你会发现它实际上是一个“库缺陷”。符合C ++的实现根本无法处理参考参数。 mem_fun_ref返回具有嵌套typedef(
)的类的对象argument_type, first_argument_type, second_argument_type
)不删除引用。 bind1st和bind2nd被指定为具有operator(),它将引用作为参数。如果argument_type已经是引用,则无法编译。
一种解决方案可能是用您自己的模板魔术替换memfunref,并删除嵌套的argument_type typedef的引用。
答案 3 :(得分:0)
实际上,编译器错误消息告诉了整个故事:
错误C2529:'_ Right':对引用的引用是非法的
std :: binders将其参数作为引用 - 您无法传递对引用的引用。
没办法。