代码之家  ›  专栏  ›  技术社区  ›  Naveen

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

  •  3
  • Naveen  · 技术社区  · 16 年前

    我有一个这样简单的班级:

    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:“右”:引用 引用是非法的

    如果我移除参数f()中的引用,它编译得很好。如何解决此问题?我不想删除引用,因为在我的实际代码中,复制对象的成本相当高。另外,我没有使用Boost。

    4 回复  |  直到 16 年前
        1
  •  5
  •   Pavel Minaev    16 年前

    对不起,你做不容易。把它当作一个不包括在 std::bind1st std::bind2nd (有点像三元函数等)。助推会有帮助- boost::bind 透明地支持引用,并且 boost::ref .

    如果您的实现支持TR1(最新的G++版本和VC++2008 SP1都支持),那么您可以使用 std::tr1::bind ,这在很大程度上与 Boost::绑定 ,但标准化。

        2
  •  2
  •   Loki Astari    16 年前

    我不相信你能把参数绑定到一个引用的方法上。(不是在STL中,我认为Boost版本可以让您这样做,但我不确定)

    你需要自己滚。

    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));
    
        3
  •  1
  •   sellibitze    16 年前

    我被同样的问题咬了一口。如果你查看C++标准,你会发现它实际上是一个“库缺陷”。一个一致的C++实现根本不能处理引用参数。mem_fun_ref返回具有嵌套typedef的类的对象(

    argument_type, first_argument_type, second_argument_type
    

    )没有删除引用的地方。bind1st和bind2nd指定有一个operator(),wich将引用作为参数。如果参数“type”已经是引用,则编译失败。

    一种解决方案可能是用您自己的模板magic替换memfunref,并去掉嵌套参数“u类型typedef”的引用。

        4
  •  0
  •   RED SOFT ADAIR    16 年前

    实际上,编译器错误消息告诉了整个过程:

    错误C2529:“右”:引用非法

    绑定器将它们的参数作为引用-不能将引用传递给引用。

    没办法。