[expr.prim.id.qual]

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

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

### 7.5.5 Names [[expr.prim.id]](expr.prim.id#qual)

#### 7.5.5.3 Qualified names [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*](expr.prim.id.unqual#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](#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*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")[.](#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]")[.](#1.sentence-2)

[2](#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]")[.](#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[.](#2.sentence-2)

[*Example [1](#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](#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)](#3.1)

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

- [(3.2)](#3.2)

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

- [(3.3)](#3.3)

a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") that is the [*id-expression*](expr.prim.id.general#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)](#3.4)

a declarative [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.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]")[.](#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[.](#3.sentence-3)

[4](#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)](#4.1)

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

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

- [(4.3)](#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[.](#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]")[.](#4.3.sentence-2)

- [(4.4)](#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[.](#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[.](#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[.](#4.4.sentence-3)

- [(4.5)](#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[.](#4.5.sentence-1)
  T shall be a class template[.](#4.5.sentence-2)

  * [(4.5.1)](#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"))[.](#4.5.1.sentence-1)

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

- [(4.6)](#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]")[.](#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[.](#4.6.sentence-2)

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

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

[7](#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)](#7.1)

a variable
declared outside of C of object type T,

- [(7.2)](#7.2)

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

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

[8](#8)

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

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

[9](#9)

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

The result is an lvalue if the member is

- [(9.1)](#9.1)

a function other than a non-static member function,

- [(9.2)](#9.2)

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

- [(9.3)](#9.3)

a variable,

- [(9.4)](#9.4)

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

- [(9.5)](#9.5)

a data member,

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