Skip to content

CWG2569 [expr.prim.id.unqual] Use of decltype(capture) in parameter-declaration-clause #31

@brevzin

Description

@brevzin

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions