[expr.prim.id]

# 7 Expressions [[expr]](./#expr)

## 7.5 Primary expressions [[expr.prim]](expr.prim#id)

### 7.5.5 Names [expr.prim.id]

#### [7.5.5.1](#general) General [[expr.prim.id.general]](expr.prim.id.general)

[id-expression:](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]")  
[*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")  
[*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]")  
[*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]")

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1368)

An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is a restricted form of a[*primary-expression*](expr.prim.grammar#nt:primary-expression "7.5.1 Grammar [expr.prim.grammar]")[.](#general-1.sentence-1)

[*Note [1](#general-note-1)*:

An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") can appear after[. and -> operators](expr.ref "7.6.1.5 Class member access [expr.ref]")[.](#general-1.sentence-2)

â *end note*]

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1378)

If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") E denotes
a non-static non-type member of some class C at a point where
the current class ([[expr.prim.this]](expr.prim.this "7.5.3 This")) is X and

- [(2.1)](#general-2.1)

E is potentially evaluated orC is X or a base class of X, and

- [(2.2)](#general-2.2)

E is not the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of
a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access")), and

- [(2.3)](#general-2.3)

E is not the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of
a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") ([[expr.reflect]](expr.reflect "7.6.2.10 The reflection operator")), and

- [(2.4)](#general-2.4)

if E is a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]"),E is not the un-parenthesized operand of
the unary & operator ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")),

the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is transformed into
a class member access expression using (*this) as the object expression[.](#general-2.sentence-1)

If this transformation occurs
in the predicate of a precondition assertion of a constructor of X or a postcondition assertion of a destructor of X,
the expression is ill-formed[.](#general-2.sentence-2)

[*Note [2](#general-note-2)*:

If C is not X or a base class of X,
the class member access expression is ill-formed[.](#general-2.sentence-3)

Also, if the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") occurs within
a static or explicit object member function,
the class member access is ill-formed[.](#general-2.sentence-4)

â *end note*]

This transformation does not apply in
the template definition context ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types"))[.](#general-2.sentence-5)

[*Example [1](#general-example-1)*: struct C {bool b;
 C() pre(b) // error pre(&this->b) // OK pre(sizeof(b) > 0); // OK, b is not potentially evaluated.}; â *end example*]

[3](#general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1423)

If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") E denotes
a member M of an anonymous union ([[class.union.anon]](class.union.anon "11.5.2 Anonymous unions")) U:

- [(3.1)](#general-3.1)

  If U is a non-static data member,E refers to M as a member of the lookup context of the terminal name of E (after any implicit transformation to
a class member access expression)[.](#general-3.1.sentence-1)
  [*Example [2](#general-example-2)*:
  o.x is interpreted as o.u.x,
where u names the anonymous union member[.](#general-3.1.sentence-2)
 â *end example*]

- [(3.2)](#general-3.2)

  Otherwise, E is interpreted as a class member access ([[expr.ref]](expr.ref "7.6.1.5 Class member access"))
that designates the member subobject M of
the anonymous union variable for U[.](#general-3.2.sentence-1)
  [*Note [3](#general-note-3)*:
  Under this interpretation, E no longer denotes a non-static data member[.](#general-3.2.sentence-2)
 â *end note*]
  [*Example [3](#general-example-3)*:
  N​::​x is interpreted as N​::​u.x,
where u names the anonymous union variable[.](#general-3.2.sentence-3)
 â *end example*]

[4](#general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1449)

An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") that designates a non-static data member or
implicit object member function of a class can only be used:

- [(4.1)](#general-4.1)

as part of a class member access
(after any implicit transformation (see above))
in which the
object expression
refers to the member's class
or a class derived from
that class, or

- [(4.2)](#general-4.2)

to form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")), or

- [(4.3)](#general-4.3)

if that [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") designates a non-static data member
and it appears in an unevaluated operand[.](#general-4.sentence-1)
  [*Example [4](#general-example-4)*: struct S {int m;};int i = sizeof(S::m); // OKint j = sizeof(S::m + 42); // OKint S::*k = &[:^^S::m:]; // OK â *end example*]

[5](#general-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1479)

For an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that denotes an overload set,
overload resolution is performed
to select a unique function ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set"))[.](#general-5.sentence-1)

[*Note [4](#general-note-4)*:

A program cannot refer to a function
with a trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") whose [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") is not satisfied,
because such functions are never selected by overload resolution[.](#general-5.sentence-2)

[*Example [5](#general-example-5)*: template<typename T> struct A {static void f(int) requires false;};

void g() { A<int>::f(0); // error: cannot call fvoid (*p1)(int) = A<int>::f; // error: cannot take the address of fdecltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>​::​f) is invalid}

In each case, the constraints of f are not satisfied[.](#general-5.sentence-3)

In the declaration of p2,
those constraints need to be satisfied
even thoughf is an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]")[.](#general-5.sentence-4)

â *end example*]

â *end note*]

#### [7.5.5.2](#unqual) Unqualified names [[expr.prim.id.unqual]](expr.prim.id.unqual)

[unqualified-id:](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")  
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")  
[*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1 General [over.oper.general]")  
[*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]")  
[*literal-operator-id*](over.literal#nt:literal-operator-id "12.6 User-defined literals [over.literal]")  
~ [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]")  
~ [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]")  
[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")

[1](#unqual-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1521)

An [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is only
an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") if it has
been suitably declared ([[dcl]](dcl "9 Declarations"))
or if it appears as part of a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))[.](#unqual-1.sentence-1)

[*Note [1](#unqual-note-1)*:

For [*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1 General [over.oper.general]")*s*, see [[over.oper]](over.oper "12.4 Overloaded operators"); for[*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]")*s*, see [[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions"); for[*literal-operator-id*](over.literal#nt:literal-operator-id "12.6 User-defined literals [over.literal]")*s*, see [[over.literal]](over.literal "12.6 User-defined literals"); for[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")*s*, see [[temp.names]](temp.names "13.3 Names of template specializations")[.](#unqual-1.sentence-2)

A [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") or [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") prefixed by ~ denotes the destructor of the type so named;
see [[expr.prim.id.dtor]](#dtor "7.5.5.5 Destruction")[.](#unqual-1.sentence-3)

â *end note*]

[2](#unqual-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1537)

A [*component name*](#def:component_name "7.5.5.2 Unqualified names [expr.prim.id.unqual]") of an [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") U is

- [(2.1)](#unqual-2.1)

U if it is a name or

- [(2.2)](#unqual-2.2)

the component name of
the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") or [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") of U, if any[.](#unqual-2.sentence-1)

[*Note [2](#unqual-note-2)*:

Other constructs that contain names to look up can have several
component names ([[expr.prim.id.qual]](#qual "7.5.5.3 Qualified names"), [[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers"), [[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"), [[dcl.mptr]](dcl.mptr "9.3.4.4 Pointers to members"), [[namespace.udecl]](namespace.udecl "9.10 The using declaration"), [[temp.param]](temp.param "13.2 Template parameters"), [[temp.names]](temp.names "13.3 Names of template specializations"), [[temp.res]](temp.res "13.8 Name resolution"))[.](#unqual-2.sentence-2)

â *end note*]

The [*terminal name*](#def:name,terminal "7.5.5.2 Unqualified names [expr.prim.id.unqual]") of a construct is
the component name of that construct that appears lexically last[.](#unqual-2.sentence-3)

[3](#unqual-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1554)

The result is the entity denoted by
the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup"))[.](#unqual-3.sentence-1)

[4](#unqual-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1558)

If

- [(4.1)](#unqual-4.1)

the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") appears in a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") at program point P,

- [(4.2)](#unqual-4.2)

the entity is a local entity ([[basic.pre]](basic.pre "6.1 Preamble"))
or a variable declared by an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") ([[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3 Captures")),

- [(4.3)](#unqual-4.3)

naming the entity within the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of
the innermost enclosing [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") of P,
but not in an unevaluated operand, would refer to an entity captured by copy
in some intervening [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]"), and

- [(4.4)](#unqual-4.4)

P is in the function parameter scope,
but not the [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]"),
of the innermost such [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") E,

then
the type of the expression is
the type of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access"))
naming the non-static data member
that would be declared for such a capture
in the object parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) of the function call operator of E[.](#unqual-4.sentence-1)

[*Note [3](#unqual-note-3)*:

If E is not declared mutable,
the type of such an identifier will typically be const qualified[.](#unqual-4.sentence-2)

â *end note*]

[5](#unqual-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1589)

Otherwise,
if the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") names a coroutine parameter,
the type of the expression is
that of the copy of the parameter ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions")),
and the result is that copy[.](#unqual-5.sentence-1)

[6](#unqual-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1597)

Otherwise,
if the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") names a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object"))
attached to a function *f* with return type U,

- [(6.1)](#unqual-6.1)

if U is âreference to Tâ,
then the type of the expression isconst T;

- [(6.2)](#unqual-6.2)

otherwise,
the type of the expression is const U[.](#unqual-6.sentence-1)

[7](#unqual-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1613)

Otherwise,
if the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") appears in the predicate of a contract assertion C ([[basic.contract]](basic.contract "6.11 Contract assertions"))
and the entity is

- [(7.1)](#unqual-7.1)

a variable
declared outside of C of object type T,

- [(7.2)](#unqual-7.2)

a variable or template parameter
declared outside of C of type âreference to Tâ, or

- [(7.3)](#unqual-7.3)

a structured binding
of type T whose corresponding variable
is declared outside of C,

then the type of the expression is const T[.](#unqual-7.sentence-1)

[8](#unqual-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1635)

[*Example [1](#unqual-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) // 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 *thisint 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)); // OKint h() post(r : ++r) // error: attempting to modify const lvalue post(r: [=] mutable {++r; // OK, refers to member of closure typereturn true; }()); int& k() post(r : ++r); // error: attempting to modify const lvalue}; â *end example*]

[9](#unqual-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1687)

Otherwise, if the entity is a template parameter object for
a template parameter of type T ([[temp.param]](temp.param "13.2 Template parameters")),
the type of the expression is const T[.](#unqual-9.sentence-1)

[10](#unqual-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1692)

In all other cases, the type of the expression is the type of the entity[.](#unqual-10.sentence-1)

[11](#unqual-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1695)

[*Note [4](#unqual-note-4)*:

The type will be adjusted as described in [[expr.type]](expr.type "7.2.2 Type") if it is cv-qualified or is a reference type[.](#unqual-11.sentence-1)

â *end note*]

[12](#unqual-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1701)

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]](dcl.struct.bind "9.7 Structured binding declarations")),
result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object")),
data member, or
template parameter object;
and a prvalue otherwise ([[basic.lval]](basic.lval "7.2.1 Value category"));
it is a bit-field if the identifier designates a bit-field[.](#unqual-12.sentence-1)

[13](#unqual-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1714)

If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") 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]](class.temporary "6.8.7 Temporary objects"),

- [(13.1)](#unqual-13.1)

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

- [(13.2)](#unqual-13.2)

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[.](#unqual-13.sentence-1)

[14](#unqual-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1737)

If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") 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]](class.temporary "6.8.7 Temporary objects"),
and the postcondition assertion
is sequenced before the initialization of the result object ([[expr.call]](expr.call "7.6.1.3 Function call")),E refers to the most recently initialized such temporary object[.](#unqual-14.sentence-1)

[*Example [2](#unqual-example-2)*: void f() {float x, &r = x; [=]() -> decltype((x)) { // lambda returns float const& because this lambda is not mutable and// x is an lvaluedecltype(x) y1; // y1 has type floatdecltype((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*]

[15](#unqual-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1777)

An [*implicitly movable entity*](#def:entity,implicitly_movable "7.5.5.2 Unqualified names [expr.prim.id.unqual]") is
a variable with automatic storage duration
that is either a non-volatile object or
an rvalue reference to a non-volatile object type[.](#unqual-15.sentence-1)

An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or[*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ([[expr.prim.splice]](expr.prim.splice "7.5.9 Expression splicing"))
is [*move-eligible*](#def:move-eligible "7.5.5.2 Unqualified names [expr.prim.id.unqual]") if

- [(15.1)](#unqual-15.1)

it designates an implicitly movable entity,

- [(15.2)](#unqual-15.2)

it is the (possibly parenthesized)
operand of a return ([[stmt.return]](stmt.return "8.8.4 The return statement")) orco_return ([[stmt.return.coroutine]](stmt.return.coroutine "8.8.5 The co_­return statement")) statement or
of a [*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]") ([[expr.throw]](expr.throw "7.6.18 Throwing an exception")), and

- [(15.3)](#unqual-15.3)

each intervening scope between
the declaration of the entity and
the innermost enclosing scope of the expression
is a block scope and,
for a [*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]"),
is not the block scope of
a [*try-block*](except.pre#nt:try-block "14.1 Preamble [except.pre]") or [*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]")[.](#unqual-15.sentence-2)

#### [7.5.5.3](#qual) Qualified names [[expr.prim.id.qual]](expr.prim.id.qual)

[qualified-id:](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]")  
[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")

[nested-name-specifier:](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")  
::  
[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") ::  
[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") ::  
[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ::  
[*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ::  
[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ::  
[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") ::

[splice-scope-specifier:](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")  
[*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]")  
templateopt [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]")

[1](#qual-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1832)

The component names of a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") are those of
its [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")[.](#qual-1.sentence-1)

The component names of a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") are
its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") (if any) and those of its[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]"), and/or[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#qual-1.sentence-2)

[2](#qual-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1843)

A [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") that is not followed by ​::​ is never interpreted as part of a [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#qual-2.sentence-1)

The keyword template may only be omitted
from the formtemplateopt [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") ​::​ when the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") is preceded by typename[.](#qual-2.sentence-2)

[*Example [1](#qual-example-1)*: template<int V>struct TCls {static constexpr int s = V; using type = int;};

int v1 = [:^^TCls<1>:]::s;int v2 = template [:^^TCls:]<2>::s; // OK, template binds to [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")typename [:^^TCls:]<3>::type v3 = 3; // OK, typename binds to the qualified nametemplate [:^^TCls:]<3>::type v4 = 4; // OK, template binds to the [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")typename template [:^^TCls:]<3>::type v5 = 5; // OK, same as v3[:^^TCls:]<3>::type v6 = 6; // error: unexpected < â *end example*]

[3](#qual-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1870)

A [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is [*declarative*](#def:declarative "7.5.5.3 Qualified names [expr.prim.id.qual]") if it is part of

- [(3.1)](#qual-3.1)

a [*class-head-name*](class.pre#nt:class-head-name "11.1 Preamble [class.pre]"),

- [(3.2)](#qual-3.2)

an [*enum-head-name*](dcl.enum#nt:enum-head-name "9.8.1 Enumeration declarations [dcl.enum]"),

- [(3.3)](#qual-3.3)

a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") that is the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]"), or

- [(3.4)](#qual-3.4)

a declarative [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#qual-3.sentence-1)

A declarative [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") shall not have a [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") or
a [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#qual-3.sentence-2)

A declaration that uses a declarative [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") shall be a friend declaration or
inhabit a scope that contains the entity being redeclared or specialized[.](#qual-3.sentence-3)

[4](#qual-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1890)

The entity designated by a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is determined as follows:

- [(4.1)](#qual-4.1)

  The [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ​::​ designates
the global namespace[.](#qual-4.1.sentence-1)

- [(4.2)](#qual-4.2)

  A [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") with a [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") designates the same type designated by the [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]"),
which shall be a class or enumeration type[.](#qual-4.2.sentence-1)

- [(4.3)](#qual-4.3)

  For a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of
the form [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") ​::​,
the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") shall designate
a class or enumeration type or a namespace[.](#qual-4.3.sentence-1)
  The [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") designates the same entity
as the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]")[.](#qual-4.3.sentence-2)

- [(4.4)](#qual-4.4)

  For a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of
the formtemplateopt [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") ​::​,
the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") of
the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") shall designate
a class template or an alias template T[.](#qual-4.4.sentence-1)
  Letting S be the specialization of T corresponding to the template argument list of
the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]"),S shall either be a class template specialization or
an alias template specialization that denotes a class or enumeration type[.](#qual-4.4.sentence-2)
  The [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") designates the underlying entity of S[.](#qual-4.4.sentence-3)

- [(4.5)](#qual-4.5)

  If a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") N is declarative and
has a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") with a template argument list A that involves a template parameter,
let T be the template nominated by N without A[.](#qual-4.5.sentence-1)
  T shall be a class template[.](#qual-4.5.sentence-2)

  * [(4.5.1)](#qual-4.5.1)

      If A is the template argument list ([[temp.arg]](temp.arg "13.4 Template arguments")) of
the corresponding [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") H ([[temp.mem]](temp.mem "13.7.3 Member templates")),N designates the primary template of T;H shall be equivalent to
the [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") of T ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading"))[.](#qual-4.5.1.sentence-1)

  * [(4.5.2)](#qual-4.5.2)

      Otherwise, N designates the partial specialization ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization")) of T whose template argument list is equivalent to A ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading"));
the program is ill-formed if no such partial specialization exists[.](#qual-4.5.2.sentence-1)

- [(4.6)](#qual-4.6)

  Any other [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") designates
the entity denotes by its[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]"), or[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")[.](#qual-4.6.sentence-1)
  If the [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is not declarative,
the entity shall not be a template[.](#qual-4.6.sentence-2)

[5](#qual-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1951)

A [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") shall not be of the form[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt ~[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") nor of the form[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ​::​ ~ [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]")[.](#qual-5.sentence-1)

[6](#qual-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1958)

The result of a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Q is
the entity it denotes ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup"))[.](#qual-6.sentence-1)

[7](#qual-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1962)

If Q appears
in the predicate of a contract assertion C ([[basic.contract]](basic.contract "6.11 Contract assertions"))
and the entity is

- [(7.1)](#qual-7.1)

a variable
declared outside of C of object type T,

- [(7.2)](#qual-7.2)

a variable
declared outside of C of type âreference to Tâ, or

- [(7.3)](#qual-7.3)

a structured binding of type T whose corresponding variable
is declared outside of C,

then the type of the expression is const T[.](#qual-7.sentence-1)

[8](#qual-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1983)

Otherwise, the type of the expression is the type of the result[.](#qual-8.sentence-1)

[9](#qual-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1986)

The result is an lvalue if the member is

- [(9.1)](#qual-9.1)

a function other than a non-static member function,

- [(9.2)](#qual-9.2)

a non-static member function
if Q is the operand of a unary & operator,

- [(9.3)](#qual-9.3)

a variable,

- [(9.4)](#qual-9.4)

a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations")), or

- [(9.5)](#qual-9.5)

a data member,

and a prvalue otherwise[.](#qual-9.sentence-1)

#### [7.5.5.4](#expr.prim.pack.index) Pack indexing expression [[expr.prim.pack.index]](expr.prim.pack.index)

[pack-index-expression:](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]")  
[*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") ... [ [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") ]

[1](#expr.prim.pack.index-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2010)

The [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") P in a [*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") shall be an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that denotes a pack[.](#expr.prim.pack.index-1.sentence-1)

[2](#expr.prim.pack.index-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2014)

The [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") shall be
a converted constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type std​::​size_t whose value V, termed the index,
is such that 0â¤V<sizeof...(P)[.](#expr.prim.pack.index-2.sentence-1)

[3](#expr.prim.pack.index-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2020)

A [*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#expr.prim.pack.index-3.sentence-1)

[4](#expr.prim.pack.index-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2023)

[*Note [1](#expr.prim.pack.index-note-1)*:

A [*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") denotes
the Vth element of the pack[.](#expr.prim.pack.index-4.sentence-1)

â *end note*]

#### [7.5.5.5](#dtor) Destruction [[expr.prim.id.dtor]](expr.prim.id.dtor)

[1](#dtor-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2031)

An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that denotes the destructor of a type T names the destructor of T if T is a class type ([[class.dtor]](class.dtor "11.4.7 Destructors")),
otherwise the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is said
to name a [*pseudo-destructor*](#def:pseudo-destructor "7.5.5.5 Destruction [expr.prim.id.dtor]")[.](#dtor-1.sentence-1)

[2](#dtor-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2040)

If the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") names a pseudo-destructor,T shall be a scalar type and
the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") shall appear
as the right operand of a class member access ([[expr.ref]](expr.ref "7.6.1.5 Class member access")) that forms
the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") of a function call ([[expr.call]](expr.call "7.6.1.3 Function call"))[.](#dtor-2.sentence-1)

[*Note [1](#dtor-note-1)*:

Such a call ends the lifetime of the object ([[expr.call]](expr.call "7.6.1.3 Function call"), [[basic.life]](basic.life "6.8.4 Lifetime"))[.](#dtor-2.sentence-2)

â *end note*]

[3](#dtor-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2050)

[*Example [1](#dtor-example-1)*: struct C { };void f() { C * pc = new C; using C2 = C;
 pc->C::~C2(); // OK, destroys *pc C().C::~C(); // undefined behavior: temporary of type C destroyed twiceusing T = int; 0 .T::~T(); // OK, no effect0.T::~T(); // error: 0.T is a [*user-defined-floating-point-literal*](lex.ext#nt:user-defined-floating-point-literal "5.13.9 User-defined literals [lex.ext]") ([[lex.ext]](lex.ext "5.13.9 User-defined literals"))} â *end example*]
