【问题标题】:Overloading operator>> for lambdas用于 lambda 的重载运算符>>
【发布时间】:2014-05-11 09:41:43
【问题描述】:

更新3: 请转至overloading operators for lamdas

我想在 c++11/14 中为 lambdas 重载 operator>>

这是一个简单的代码:

#include<iostream>
#include<functional>
#include<vector>

using namespace std;

template <typename R,typename T>
void operator >> (vector<T>& v, function<R(T)> f){
    for(auto& e : v)
       f(e);
}

int main(){
   vector<int> v = { 1,2,3,4,5,6,7};
   auto l = [](int i) { cout << i*i << endl; };
   v >> function<void(int)>(l);
}

但我真正想要的是:

v >> l; //(I)
v >> [](int i) { cout << i*i << endl; }; //(II)

并摆脱function&lt;F&gt;

我从一个类似的问题How to overload an operator for composition of functionals in C++0x?得到一些想法

尤其是第二个答案中的这段代码重载了两个 lambda 表达式的 &gt;&gt; 运算符。

#include <iostream>

template <class LAMBDA, class ARG>
auto apply(LAMBDA&& l, ARG&& arg) -> decltype(l(arg))
{
  return l(arg);
}

template <class LAMBDA1, class LAMBDA2>
class compose_class
{
public:
  LAMBDA1 l1;
  LAMBDA2 l2;

  template <class ARG>
  auto operator()(ARG&& arg) -> 
    decltype(apply(l2, apply(l1, std::forward<ARG>(arg))))
  { return apply(l2, apply(l1, std::forward<ARG>(arg))); }

  compose_class(LAMBDA1&& l1, LAMBDA2&& l2) 
    : l1(std::forward<LAMBDA1>(l1)),l2(std::forward<LAMBDA2>(l2))     {}
};

template <class LAMBDA1, class LAMBDA2>
auto operator>>(LAMBDA1&& l1, LAMBDA2&& l2) ->compose_class<LAMBDA1, LAMBDA2>
{
  return compose_class<LAMBDA1, LAMBDA2>
    (std::forward<LAMBDA1>(l1), std::forward<LAMBDA2>(l2));
}

int main()
{    
  auto l1 = [](int i) { return i + 2; };
  auto l2 = [](int i) { return i * i; };

  std::cout << (l1 >> l2)(3) << std::endl;
}

但对于我的简单示例,我仍然不知道如何重载 &gt;&gt; 运算符。

更新: 我实际上希望能够为不同的重载“>>”运算符 具有不同数量参数的 lambda。

v >> [](int i) { } // calls the overload with one lambda argument
v >> [](int i1,int i2) { } // calls another overload with two lambda arguments

更新 2: 我想我没有解释我真正想要什么,我问了一个新问题operator overloading for lambdas?

我已经详细解释了该问题中的问题。

【问题讨论】:

    标签: c++ c++11 lambda operator-overloading


    【解决方案1】:

    也许下面的代码可以完成这项工作:

    #include<iostream>
    #include<functional>
    #include<vector>
    
    using namespace std;
    
    template <typename R, typename T>
    void operator >> (vector<T>& v, R f){
        for(auto& e : v)
           f(e);
    }
    
    int main(){
       vector<int> v = { 1,2,3,4,5,6,7};
       auto l = [](int i) { cout << i*i << endl; };
       v >> function<void(int)>(l);
       v >> l; //(I)
       v >> [](int i) { cout << i*i << endl; }; //(II)
    }
    

    更新:

    [OP 更新]:我实际上希望能够为不同的重载 '>>' 运算符 具有不同数量参数的 lambda。

    您可以使用std::bind 来传递具有任意数量输入参数的不同 lambda(参见下面的代码):

    #include<iostream>
    #include<functional>
    #include<vector>
    
    using namespace std;
    
    template <typename T, typename F>
    void operator >> (vector<T>& v, F f){
      for (auto& e : v) f(e);
    }
    
    int main(){
      using namespace std::placeholders;
      vector<int> v = { 1, 2, 3, 4, 5, 6, 7 };
      v >> std::bind([](int i, int j){ cout << i*j << " "; }, _1, 2);
      cout << endl;
      v >> std::bind(
             [](int i, double d1, double d2)
               { 
                 cout << (static_cast<double>(i) * d1 / d2) << " "; 
               }, 
               _1, 2.0, 3.0);
      cout << endl;
      return 0;
    }
    

    HTH

    【讨论】:

    • 在这个简单的示例中,您的解决方案有效(谢谢)。但是如果我想为具有不同数量参数的不同 lambdas 重载 >> 运算符,那么它不会。
    • @amin 您如何想象在模板二进制 operator&gt;&gt; 中为 Lambda 表达式传递额外任意数量的输入参数?
    • vector&lt;int&gt; 只是一个简单的例子。我不想带来与问题无关的实际代码。(它是 sqlite C 库的包装器,我有一个查询类,我想重载 >> 运算符以从查询中提取不同数量的列)
    • 我想我没有解释我真正想要什么,我问了一个新问题,请看stackoverflow.com/questions/23594969/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多