-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Reference (section label): [expr.prim.id.unqual]
Issue description:
P2036 changed the scope of lambda's trailing-return-type and also tried to clean a few things up with respect to use of capture in certain contexts. The problem with unevaluated use of capture early in lambdas is that we don't yet know if the lambda is mutable
and so we don't know how to interpret the capture. The paper made problematic uses of capture ill-formed.
The problem is, there are some uses of such in the wild. As in libstdc++, which has a lambda that looks like this:
[local_end](decltype(local_end) it){ return it != local_end; };
Since P2036 was a DR, this retroactively breaks libstdc++.
While many unevaluated uses of capture can be be problematic -- decltype(f(local_end))
could be, for instance -- this specific case of decltype(unparenthesized-id-that-names-a-capture)
is totally fine. We could carve out this specific case to avoid retroactively breaking libstdc++.
Suggested resolution:
Add the carve out to this bullet:
- If either P is in E’s function parameter scope but not its parameter-declaration-clause or the unqualified-id is the expression of a decltype-specifier, then the type of the expression is the type of a class member access expression ([expr.ref]) naming the non-static data member that would be declared for such a capture in the object parameter ([dcl.fct]) of the function call operator of E.
And then change the example:
+ [=]<decltype(x) P>{}; // ok: P has type float
- [=]<decltype(x) P>{}; // error: x refers to local entity but precedes the
+ [=]<decltype((x)) P>{}; // error: x refers to local entity but precedes the
// lambda's function parameter scope
[=](decltype((x)) y){}; // error: x refers to local entity but is in the lambda's
// [parameter-declaration-clause](https://eel.is/c++draft/dcl.fct#nt:parameter-declaration-clause)