Should I pass a lambda by const reference.

前端 未结 3 1855
我寻月下人不归
我寻月下人不归 2020-12-29 09:24

Typically I use the following pattern when accepting a lambda as an argument to a function (A template class passed-by-value):

template 

        
3条回答
  •  余生分开走
    2020-12-29 09:59

    A copy is a copy, so you cannot mutate the original, might have some performance impact when a lot of data is involved:

    #include 
    using namespace std;
    
    template
    void call_value(Fn f) { f(); }
    template
    void call_ref(Fn & f) { f(); }
    template
    void call_cref(Fn const & f) { f(); }
    
    struct Data {
      Data() {}
      Data(Data const &) {
        cout << "copy" << endl;
      }
      Data(Data &&) {
        cout << "move" << endl;
      }
    };
    
    int main(int, char **) {
      Data data;
    
      auto capref = [&data] () {};
      cout << "capture by value, so we get a ";
      auto capcp = [data] () {};
    
      cout << " the lambda with a reference ... ";
      call_value(capref);
      cout << " could now be called and mutate .. ";
      call_ref(capref);
      call_cref(capref);
      cout << " but won't, as it had to be declared mutable " << endl;
    
      cout << "the lambda with an instance: ";
      call_value(capcp);
      cout << "but not ";
      call_ref(capcp);
      call_cref(capcp);
      cout << " the reference versions " << endl;
    
      bool en = false;
      auto trigger = [en](bool enable = true) mutable {
        if (en) {
          cout << "fire!" << endl;
        }
        if (en or enable) {
          en = true;
        }
      };
      cout << "won't shoot" << endl;
      trigger(false);
      call_value(trigger);
      trigger(false);
      call_ref(trigger);
      cout << "and now ... ";
      trigger(false);
      // const ref won't work
      return 0;
    }
    

    See it in action.

    Don't forget: lambdas are mere syntactic sugar for callable classes. (But extremely helpful)

提交回复
热议问题