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

有可能使用Boost的C++匿名函数吗?

  •  6
  • Steve  · 技术社区  · 16 年前

    我试图解决一个匿名函数的问题,它会变得简单很多,并且怀疑C++是否有可能。

    我想做的是(基本上)

    template<typename T>
    T DoSomething(T one, function<T(T)> dosomething)
    {
        return one + dosomething(5);
    }
    
    void GetMyVal(...)
    {
       DoSomething<int>(1, /*anonymous func here*/)
    }
    

    这个例子对于我要做的事情非常,非常简单。在C#我会做p=>我知道用C++0x很容易,但我不能用它。我觉得我应该可以用boost::lambda或者boost::bind和boost::function与占位符的组合来完成它,但我似乎无法让它工作。这可能是不可能的,这也很好,但请回答,如果这是不可能的。谢谢。

    编辑: 好吧,看起来int的简单例子很好用,那么更复杂的结构呢?所以,让我们试试

    struct NumHolder
    {
      int x;
    }
    
    template<typename T>
    T DoSomething(T one, function<T(NumHolder)> dosomething)
    {
        NumHolder temp;
        temp = 5
        return one + dosomething(temp);
    }
    
    void GetMyVal(...)
    {
       DoSomething<int>(1, /*anonymous func here*/)
    }
    

    这里我的C表达式是沿着p=>P.TEMP* 5。这可以在C++中用Boost进行吗?

    编辑2:好的,现在我只是好奇:D如何在lambda表达式中调用函数?所以,如果我们有

    int ChangeVal(int mult)
    {
        return mult*5;
    }
    
    struct NumHolder
    {
      int x;
    }
    
    template<typename T>
    T DoSomething(T one, function<T(NumHolder)> dosomething)
    {
        NumHolder temp;
        temp = 5
        return one + dosomething(temp);
    }
    
    void GetMyVal(...)
    {
       DoSomething<int>(1, /*anonymous func here*/)
    }
    

    3 回复  |  直到 16 年前
        1
  •  5
  •   Éric Malenfant    16 年前

    正如Anders在回答中指出的那样,boost::lambda可能很有用,但在某些情况下,代码可能变得难以阅读。因此,这取决于你想在匿名函数中做什么。

    对于像 p => p * 5

    DoSomething(1, _1 * 5);
    

    您的第二个示例遇到了语法很快变得冗长的一个区域:成员(数据或函数)访问。因为“点”运算符不能在C++中超载,所以必须使用绑定表达式从参数中获得“x”:

    DoSomething(1, bind(&NumHolder::x, _1) * 5);
    

    或者,对于Boost.Lambda,使用重载->*操作员:

    DoSomething(1, &_1->* &NumHolder::x * 5);
    

    好吧,最后一次:) 在你的最后一个问题中,你用C写,你会 p => ChangeVal(p) ,但上面的代码显示 ChangeVal 取int,不是NumHolder,所以不清楚你的意思。

    假设ChangeVal取int,并且您希望匿名函数执行 ChangeVal(the_arg.x) ,你可以用Boost写这个。Lambda:

    DoSomething(1, bind(&ChangeVal, &_1->*&NumHolder::x));
    

    DoSomething(1, bind(&ChangeVal, bind(&NumHolder::x, _1));
    
        2
  •  2
  •   Anders Abel    16 年前

    我认为相当于C# p=>p*5 _1*5

        3
  •  0
  •   Andrey    16 年前