Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of specifying captured variable in lambda expression?

Tags:

c++

c++11

lambda

I have this code:

int i = 0; [&i](){i++;}(); 

But I can omit i and just use:

[&](){i++;}(); 

What is the purpose of specifying &i? (and similarly =var and =). Is it affecting compile time or runtime performance?

like image 470
SwiftMango Avatar asked Aug 28 '13 19:08

SwiftMango


People also ask

What does capture mean in lambda?

The lambda is capturing an outside variable. 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 does a lambda expression specify how is it used?

A lambda expression is an anonymous function that provides a concise and functional syntax, which is used to write anonymous methods. It is based on the function programming concept and used to create delegates or expression tree types.

What is a lambda capture list?

The capture list defines what from the outside of the lambda should be available inside the function body and how. It can be either: a value: [x] a reference [&x] any variable currently in scope by reference [&]

Why local variables referenced from a lambda expression must be final or effectively Final?

Forcing the variable to be final avoids giving the impression that incrementing start inside the lambda could actually modify the start method parameter.


2 Answers

&i means only i is captured as reference, while & means all variables which are used in the lambda, are captured from the scope.

int i = 0, j = 10;  [&i]{ i++; j++;}(); //error: j is not captured by reference  [&]{ i++; j++;}(); //ok: both variables are captured by reference 

The &i approach is provided by the language to limit the amount of captured variables. C++ provides you full control on the captured variables, as to which specific variables to capture, how to capture (by value, or reference).

Same reasoning with i and =:

int i = 0, j = 10;  [i]{ i++; j++;}(); //error: j is not captured (only i is captured by value)  [=]{ i++; j++;}(); //ok: both variables are captured by value  //more [&i, j]{ i++; j++;}(); //ok: captured i by reference, j by value 

Hope that helps.

like image 58
Nawaz Avatar answered Nov 10 '22 13:11

Nawaz


Sometimes you may want to capture different variables in different ways:

std::vector<int> v { 7, 8, 9, 10, 11 }; int n = 3;  //Capture v by reference and n by value: auto getNth = [&v, n](){ return v[n]; };  //Behavior: n = 9999; getNth(); //returns 10 - changing n didn't affect the lambda v[3] = 42; getNth(); //returns 42 - changing v did affect the lambda 

This is why the more-detailed syntax is available.

like image 38
Timothy Shields Avatar answered Nov 10 '22 12:11

Timothy Shields