Lambda Expression vs Functor in C++

后端 未结 8 610
予麋鹿
予麋鹿 2020-12-05 00:01

I wonder where should we use lambda expression over functor in C++. To me, these two techniques are basically the same, even functor is more elegant and cleaner tha

相关标签:
8条回答
  • 2020-12-05 00:35

    First, i would like to clear some clutter here.

    There are two different things

    1. Lambda function
    2. Lambda expression/functor.

    Usually, Lambda expression i.e. [] () {} -> return-type does not always synthesize to closure(i.e. kind of functor). Although this is compiler dependent. But you can force compiler by enforcing + sign before [] as +[] () {} -> return-type. This will create function pointer.

    Now, coming to your question. You can use lambda repeatedly as follows:

    int main()
    {
        auto print = [i=0] () mutable {return i++;};
        cout<<print()<<endl;
        cout<<print()<<endl;
        cout<<print()<<endl;
        // Call as many time as you want
        return 0;
    }
    

    You should use Lambda wherever it strikes in your mind considering code expressiveness & easy maintainability like you can use it in custom deleters for smart pointers & with most of the STL algorithms.

    If you combine Lambda with other features like constexpr, variadic template parameter pack or generic lambda. You can achieve many things.

    You can find more about it here

    0 讨论(0)
  • 2020-12-05 00:38

    lambda and functor have context. Functor is a class and therefore can be more complex then a lambda. A function has no context.

    #include <iostream>
    #include <list>
    #include <vector>
    using namespace std;
    
    //Functions have no context, mod is always 3
    bool myFunc(int n) { return n % 3 == 0; }
    
    //Functors have context, e.g. _v
    //Functors can be more complex, e.g. additional addNum(...) method
    class FunctorV
    {
       public:
       FunctorV(int num ) : _v{num} {}
    
       void addNum(int num) { _v.push_back(num); }
    
       bool operator() (int num)
       {
          for(int i : _v) {
             if( num % i == 0)
                return true;
          }
          return false;
       }
    
       private:
       vector<int> _v;
    };
    
    void print(string prefix,list<int>& l)
    {
       cout << prefix << "l={ ";
       for(int i : l)
          cout << i << " ";
       cout << "}" << endl;
    }
    
    int main()
    {
       list<int> l={1,2,3,4,5,6,7,8,9};
       print("initial for each test: ",l);
       cout << endl;
    
       //function, so no context.
       l.remove_if(myFunc);
       print("function mod 3: ",l);
       cout << endl;
    
       //nameless lambda, context is x
       l={1,2,3,4,5,6,7,8,9};
       int x = 3;
       l.remove_if([x](int n){ return n % x == 0; });
       print("lambda mod x=3: ",l);
       x = 4;
       l.remove_if([x](int n){ return n % x == 0; });
       print("lambda mod x=4: ",l);
       cout << endl;
    
       //functor has context and can be more complex
       l={1,2,3,4,5,6,7,8,9};
       FunctorV myFunctor(3);
       myFunctor.addNum(4);
       l.remove_if(myFunctor);
       print("functor mod v={3,4}: ",l);
       return 0;
    }
    

    Output:

    initial for each test: l={ 1 2 3 4 5 6 7 8 9 }
    
    function mod 3: l={ 1 2 4 5 7 8 }
    
    lambda mod x=3: l={ 1 2 4 5 7 8 }
    lambda mod x=4: l={ 1 2 5 7 }
    
    functor mod v={3,4}: l={ 1 2 5 7 }
    
    0 讨论(0)
提交回复
热议问题