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


2838. Declaration conflicts in lambda-expressions

Section: 6.4.3  [basic.scope.block]     Status: open     Submitter: Jakub Jelínek     Date: 2023-11-30

(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 a potentially conflicts with a declaration whose target scope is the parent scope of S, the program is ill-formed.

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 a potentially conflicts with a declaration whose target scope is the program is ill-formed.