将std :: bind2nd与引用一起使用

时间:2009-09-23 07:21:32

标签: c++ stl

我有一个像这样的简单类:

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()中的引用,它编译得很好。我该如何解决这个问题?我不想删除引用,因为在我的实际代码中复制对象是非常昂贵的。另外,我没有使用提升。

4 个答案:

答案 0 :(得分:5)

抱歉,你不能轻易做到这一点。只考虑std::bind1ststd::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将其参数作为引用 - 您无法传递对引用的引用。

没办法。