[expr.prim.id.unqual] (original) (raw)
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]
The terminal name of a construct is the component name of that construct that appears lexically last.
[Note 3:
If E is not declared mutable, the type of such an identifier will typically be const qualified.
— _end note_]
Otherwise, if the unqualified-idnames 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-idnames a result binding ([dcl.contract.res]) attached to a function _f_with return type U,
- if U is “reference to T”, then the type of the expression isconst T;
- otherwise, the type of the expression is const U.
Otherwise, if the unqualified-idappears in the predicate of a contract assertion C ([basic.contract]) and the entity is
- a variable declared outside of Cof object type T,
- a variable or template parameter declared outside of Cof type “reference to T”, or
- a structured binding of type Twhose corresponding variable is declared outside of C,
then the type of the expression is const T.
[Example 1: 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) pre (++i) pre (++(*p)) pre (++r) pre (x.m()) pre (px->m()) pre ([=,&i,*this] mutable { ++n; ++i; ++p; ++r; ++this->z; ++z; int j = 17;[&]{ int k = 34;++i; ++j; ++k; }();return true;}());template <int N, int& R, int* P> void g() pre(++N) pre(++R) pre(++(*P)); int h() post(r : ++r) post(r: [=] mutable { ++r; return true;}());int& k() post(r : ++r); }; — _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.
In all other cases, the type of the expression is the type of the entity.
[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 Eappears 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 Enames 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.
[Example 2: void f() { float x, &r = x;[=]() -> decltype((x)) { decltype(x) y1; decltype((x)) y2 = y1; decltype(r) r1 = y1; decltype((r)) r2 = y2; return y2;};[=](decltype((x)) y) { decltype((x)) z = x; };[=] { [](decltype((x)) y) {}; [x=1](decltype((x)) y) { decltype((x)) z = x; };};} — _end example_]