7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.5 Names [expr.prim.id]

7.5.5.2 Unqualified names [expr.prim.id.unqual]

An identifier is only an id-expression if it has been suitably declared ([dcl]) or if it appears as part of a declarator-id ([dcl.decl]).
[Note 1: 
A type-name or computed-type-specifier prefixed by ~ denotes the destructor of the type so named; see [expr.prim.id.dtor].
— end note]
A component name of an unqualified-id U is
[Note 2: 
Other constructs that contain names to look up can have several component names ([expr.prim.id.qual], [dcl.type.simple], [dcl.type.elab], [dcl.mptr], [namespace.udecl], [temp.param], [temp.names], [temp.res]).
— end note]
The terminal name of a construct is the component name of that construct that appears lexically last.
The result is the entity denoted by the unqualified-id ([basic.lookup.unqual]).
If 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.
[Note 3: 
If E is not declared mutable, the type of such an identifier will typically be const qualified.
— end note]
[Example 1: void f() { float x, &r = x; [=]() -> decltype(x)) { / lambda returns float const& because this lambda is not mutable and / x is an lvalue decltype(x) y1; / y1 has type float decltype(x)) y2 = y1; / y2 has type float const& decltype(r) r1 = y1; / r1 has type float& decltype(r)) r2 = y2; / r2 has type float const& return y2; }; [=](decltype(x)) y) { decltype(x)) z = x; / OK, y has type float&, z has type float const& }; [=] { [](decltype(x)) y) {}; / OK, lambda takes a parameter of type float const& [x=1](decltype(x)) y) { decltype(x)) z = x; / OK, y has type int&, z has type int const& }; }; } — end example]
Otherwise, if the unqualified-id names a coroutine parameter, the type of the expression is that of the copy of the parameter ([dcl.fct.def.coroutine]), and the result is that copy.
Otherwise, if the unqualified-id names a result binding ([dcl.contract.res]) attached to a function with return type U,
  • if U is “reference to T”, then the type of the expression is const T;
  • otherwise, the type of the expression is const U.
Otherwise, if the unqualified-id appears in the predicate of a contract assertion C ([basic.contract]) and the entity is
  • a variable declared outside of C of object type T,
  • a variable or template parameter declared outside of C of type “reference to T”, or
  • a structured binding of type T whose corresponding variable is declared outside of C,
then the type of the expression is const T.
[Example 2: int n = 0; struct X { bool m(); }; struct Y { int z = 0; void f(int i, int* p, int& r, X x, X* px) pre (+n) / error: attempting to modify const lvalue pre (+i) / error: attempting to modify const lvalue pre (+(*p)) / OK pre (+r) / error: attempting to modify const lvalue pre (x.m() / error: calling non-const member function pre (px->m() / OK pre ([=,&i,*this] mutable { ++n; / error: attempting to modify const lvalue ++i; / error: attempting to modify const lvalue ++p; / OK, refers to member of closure type ++r; / OK, refers to non-reference member of closure type ++this->z; / OK, captured *this ++z; / OK, captured *this int j = 17; [&]{ int k = 34; ++i; / error: attempting to modify const lvalue ++j; / OK ++k; / OK }(); return true; }(); template <int N, int& R, int* P> void g() pre(+N) / error: attempting to modify prvalue pre(+R) / error: attempting to modify const lvalue pre(+(*P)); / OK int h() post(r : ++r) / error: attempting to modify const lvalue post(r: [=] mutable { ++r; / OK, refers to member of closure type return true; }(); int& k() post(r : ++r); / error: attempting to modify const lvalue }; — end example]
Otherwise, 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.
[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 xvalue if it is move-eligible (see below); an lvalue if the entity is a function, variable, structured binding ([dcl.struct.bind]), result binding ([dcl.contract.res]), data member, or template parameter object; and a prvalue otherwise ([basic.lval]); it is a bit-field if the identifier designates a bit-field.
If an id-expression E appears in the predicate of a function contract assertion attached to a function f and denotes a function parameter of f and the implementation introduces any temporary objects to hold the value of that parameter as specified in [class.temporary],
  • if the contract assertion is a precondition assertion and the evaluation of the precondition assertion is sequenced before the initialization of the parameter object, E refers to the most recently initialized such temporary object, and
  • if the contract assertion is a postcondition assertion, it is unspecified whether E refers to one of the temporary objects or the parameter object; the choice is consistent within a single evaluation of a postcondition assertion.
If an id-expression E names a result binding in a postcondition assertion and the implementation introduces any temporary objects to hold the result object as specified in [class.temporary], and the postcondition assertion is sequenced before the initialization of the result object ([expr.call]), E refers to the most recently initialized such temporary object.
An implicitly movable entity is a variable with automatic storage duration that is either a non-volatile object or an rvalue reference to a non-volatile object type.
An id-expression or splice-expression ([expr.prim.splice]) is move-eligible if

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant