int n; int main() { [](){ n = 0; }(); // clang says "ok" int m; [](){ m = 0; }(); // clang says "not ok" }
I just wonder:
If the lambda captures nothing, is it allowed to access global variables as per the C++ standard?
The lambda's execution takes place in a fresh local context with only its two local parameter variables, x and y ; it doesn't have access to global variables.
Variables that are created outside of a function are known as Global Variables . A global variable is one that can be accessed anywhere . This means, global variable can be accessed inside or outside of the function.
The mutable keyword is used so that the body of the lambda expression can modify its copies of the external variables x and y , which the lambda expression captures by value. Because the lambda expression captures the original variables x and y by value, their values remain 1 after the lambda executes.
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.
Yes, sure. Normal name lookup rules apply.
[expr.prim.lambda]/7 ... for purposes of name lookup ... the compound-statement is considered in the context of the lambda-expression.
Re: why local variables are treated differently from global ones.
[expr.prim.lambda]/13 ... If a lambda-expression or an instantiation of the function call operator template of a generic lambda odr-uses (3.2)
this
or a variable with automatic storage duration from its reaching scope, that entity shall be captured by the lambda-expression.[expr.prim.lambda]/9 A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression... The reaching scope of a local lambda expression is the set of enclosing scopes up to and including the innermost enclosing function and its parameters.
In your example, m
is a variable with automatic storage duration from the lambda's reaching scope, and so shall be captured. n
is not, and so doesn't have to be.
Actually the [](){ n = 10; }();
doesn't capture anything, it uses the global variable instead.
int n; int main() { [](){ n = 10; }(); // clang says "ok" std::cout << n; // output 10 }
See capture-list in Explaination
capture-list - a comma-separated list of zero or more captures, optionally beginning with a capture-default.
Capture list can be passed as follows (see below for the detailed description):
- [a,&b] where a is captured by copy and b is captured by reference.
- [this] captures the current object (*this) by reference
- [&] captures all automatic variables used in the body of the lambda by reference and current object by reference if exists
- [=] captures all automatic variables used in the body of the lambda by copy and current object by reference if exists
- [ ] captures nothing
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With