Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda capture: to use the initializer or not to use it?

Tags:

c++

lambda

c++14

Consider the following, minimal example:

int main() {
    int x = 10;    
    auto f1 = [x](){ };
    auto f2 = [x = x](){};
}

I've seen more than once such an use of the initializer [x = x], but I can't fully understand it and why I should use it instead of [x].
I can get the meaning of something like [&x = x] or [x = x + 1] (as shown in the documentation and why they differ from [x], of course, but still I can't figure out the differences between the lambdas in the example.

Are they fully interchangeable or is there any difference I can't see?

like image 783
skypjack Avatar asked Mar 23 '16 21:03

skypjack


People also ask

What does it mean to lambda capture this?

A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.

What is lambda capture list?

The capture list defines the outside variables that are accessible from within the lambda function body. The only capture defaults are. & (implicitly capture the used automatic variables by reference) and. = (implicitly capture the used automatic variables by copy).

Are lambda captures Const?

By default, variables are captured by const value . This means when the lambda is created, the lambda captures a constant copy of the outer scope variable, which means that the lambda is not allowed to modify them.

Are lambda functions faster C++?

They can capture their environment by value, by reference, and with C++14 by move. If the functionality of your callable is short and self-explanatory, use a lambda function. A lambda function is, in general, faster and easier to understand.


1 Answers

There are various corner cases that pretty much boils down to "[x = x] decays; [x] doesn't".

  • capturing a reference to function:

    void (&f)() = /* ...*/;
    [f]{};     // the lambda stores a reference to function.
    [f = f]{}; // the lambda stores a function pointer
    
  • capturing an array:

    int a[2]={};
    [a]{}     // the lambda stores an array of two ints, copied from 'a'
    [a = a]{} // the lambda stores an int*
    
  • capturing a cv-qualified thing:

    const int i = 0; 
    [i]() mutable { i = 1; } // error; the data member is of type const int
    [i = i]() mutable { i = 1; } // OK; the data member's type is int
    
like image 124
T.C. Avatar answered Nov 14 '22 22:11

T.C.