In the C ++ 14 standard ยง 5.1.2 / 12, it shows an example of a lambda expression, which, apparently, can refer to a scope variable x , although:
- the capture list is empty, i.e. no default
- The comment says it "does not commit
x "
Here is an example:
void f(int, const int (&)[2] = {}) { } // #1 void test() { const int x = 17; auto g = [](auto a) { f(x); // OK: calls #1, does not capture x }; }
See what compiles . It seems to be on x const ; if const removed, it will no longer compile for reasons that might be expected (the capture list is empty). This happens even if I make the int parameter so that it is no longer a common lambda.
How can lambda refer to x even if the capture list is empty? And how is this possible, at the same time, apparently without capturing x (as the comment says)?
The closest thing I found on this topic was someone else tangentially noticing this in a comment.
Here is the full section 5.1.2 / 12 of the standard:
A lambda expression with an associated default capture that does not explicitly capture this or a variable with automatic storage duration (this excludes any identification expression that has been found to refer to non-static member data associated with init capture) is called an implicit object capture ( i.e. this or variable), if the compound statement:
- odr uses (3.2) an object or
- denotes an object in the potentially computed expression (3.2), where the encompassing full expression depends on the general parameter of the lambda declared within the scope of the lambda expression.
[Example:
void f(int, const int (&)[2] = {}) { } // #1 void f(const int&, const int (&)[1]) { } // #2 void test() { const int x = 17; auto g = [](auto a) { f(x); // OK: calls #1, does not capture x }; auto g2 = [=](auto a) { int selector[sizeof(a) == 1 ? 1 : 2]{}; f(x, selector); // OK: is a dependent expression, so captures x }; }
-end example] All such implicitly captured objects must be declared within the scope of the lambda expression. [Note. Implicit capture of an object by a nested lambda expression can cause it to be implicitly captured using the containing lambda expression (see below). Implicit use of odr of this can lead to implicit capture. -end note]