This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
(From submission #475.)
Consider:
void foo () { auto f = [i = 5] () { int i; return 0; }; }
Before P2579R0 and P2036R3, this was ill-formed, because the capture inhabited the same scope as int i. Subclause 6.4.3 [basic.scope.block] paragraph 2 relies on the "parent" scope:
If a declaration that is not a name-independent declaration and whose target scope is the block scope S of apotentially conflicts with a declaration whose target scope is the parent scope of S, the program is ill-formed.
- compound-statement of a lambda-expression, function-body, or function-try-block,
- substatement of a selection or iteration statement that is not itself a selection or iteration statement, or
- handler of a function-try-block
However, after P2579R0, the init-capture inhabits the lambda scope (6.4.5 [basic.scope.lambda]), which is the parent of the parameter scope (6.4.4 [basic.scope.param]), which is the parent of the compound-statement scope, thus the provision does not apply. For a generic lambda, there's a template parameter scope (6.4.9 [basic.scope.temp]) in between, too:
auto f = [i = 5] <int N> () { int i; return 0; };
Possible resolution:
Change in 6.4.3 [basic.scope.block] paragraph 2 as follows, adding bullets:
If a declaration that is not a name-independent declaration and whose target scope is the block scope S of apotentially conflicts with a declaration whose target scope is
- compound-statement of a lambda-expression, function-body, or function-try-block,
- substatement of a selection or iteration statement that is not itself a selection or iteration statement, or
- handler of a function-try-block
the program is ill-formed.
- the parent scope of S or,
- if S is the block scope of a compound-statement of a lambda-expression, the nearest enclosing lambda scope of S,