Search code examples
c++templateslambdac++14perfect-forwarding

What is the benefit of && on a lambda-expression?


I'm seeing code that looks like this:

template<class Function>
void MyFunc(Function&& function) { function(...); }

What's the advantage of && here, as opposed to just copying the function by value? For reference, I'm using C++14.


Solution

  • The problem comes from avoiding copies.

    Imagine this:

    auto lambda = [ptr = std::make_unique<int>(0)]() mutable {
        std::cout << *ptr;
        ptr = std::make_unique<int>(*ptr + 1); // why not?
    };
    
    MyFunc(lambda);                     // use it normally
    MyFunc([]{ std::cout << " end"; }); // use by using a temporary lambda
    lambda()                            // just call the function after that
    

    If the signature is MyFunc(Function f), it would require a std::move and the lambda would not be useable after the call.

    If the signature is MyFunc(Function const& f), it would not work since the lambda is mutable.

    If it was MyFunc(Function& f) then the temporary would not work.

    You're basically left with MyFunc(Function&& f).


    The real question however is "Do I need to support all these cases?"

    I would tell: most of the time no. Most of the time, receiving the lambda by value is the simplest and support almost every cases. This is the way the STL went.

    Why? Because perfect forwarding of function objects is really hard to get perfect, and you cannot call the function multiple times in most of the cases in a pefectly generic way. I would perfect forward a function only if I want to wrap it, want to completely avoid copies and I expect function objects that are ref qualified to temporaries.