7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.4 Names [expr.prim.id] Unqualified names [expr.prim.id.unqual]

An identifier is only an id-expression if it has been suitably declared ([dcl.dcl]) or if it appears as part of a declarator-id ([dcl.decl]).
An identifier that names a coroutine parameter refers to the copy of the parameter ([dcl.fct.def.coroutine]).
[Note 1:
A type-name or decltype-specifier prefixed by ~ denotes the destructor of the type so named; see [expr.prim.id.dtor].
Within the definition of a non-static member function, an identifier that names a non-static member is transformed to a class member access expression ([class.mfct.non-static]).
— end note]
The result is the entity denoted by the identifier.
If the entity is a local entity and naming it from outside of an unevaluated operand within the declarative region where the unqualified-id appears would result in some intervening lambda-expression capturing it by copy ([expr.prim.lambda.capture]), 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 closure object of the innermost such intervening lambda-expression.
[Note 2:
If that lambda-expression is not declared mutable, the type of such an identifier will typically be const qualified.
— end note]
Otherwise, the type of the expression is the type of the result.
[Note 3:
If the entity is a template parameter object for a template parameter of type T ([temp.param]), the type of the expression is const T.
— end note]
[Note 4:
The type will be adjusted as described in [expr.type] if it is cv-qualified or is a reference type.
— end note]
The expression is an lvalue if the entity is a function, variable, structured binding, data member, or template parameter object and a prvalue otherwise ([basic.lval]); it is a bit-field if the identifier designates a bit-field.
[Example 1: void f() { float x, &r = x; [=] { decltype(x) y1; // y1 has type float decltype((x)) y2 = y1; // y2 has type float const& because this lambda // is not mutable and x is an lvalue decltype(r) r1 = y1; // r1 has type float& decltype((r)) r2 = y2; // r2 has type float const& }; } — end example]