[basic.lookup.qual.general]

# 6 Basics [[basic]](./#basic)

## 6.5 Name lookup [[basic.lookup]](basic.lookup#qual.general)

### 6.5.5 Qualified name lookup [[basic.lookup.qual]](basic.lookup.qual#general)

#### 6.5.5.1 General [basic.lookup.qual.general]

[1](#1)

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

Lookup of an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") followed by a ​::​ scope resolution operator
considers only
namespaces, types, and templates whose specializations are types[.](#1.sentence-1)

If a
name,[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"),[*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"), or[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") is followed by a ​::​,
it shall either be
a dependent [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ([[temp.dep.splice]](temp.dep.splice "13.8.3.5 Dependent splice specifiers")) or
it shall designate a namespace, class, enumeration, or dependent type,
and the ​::​ is never interpreted as
a complete [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#1.sentence-2)

[*Example [1](#example-1)*: class A {public:static int n;};int main() {int A;
 A::n = 42; // OK A b; // error: A does not name a type}template<int> struct B : A {};namespace N {template<int> void B(); int f() {return B<0>::n; // error: N​::​B<0> is not a type}} â *end example*]

[2](#2)

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

A member-qualified name is
the (unique) component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")), if any, of

- [(2.1)](#2.1)

an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") or

- [(2.2)](#2.2)

a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of the form[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") ​::​ or [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") ​::​

in the [*id-expression*](expr.prim.id.general#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"))[.](#2.sentence-1)

A [*qualified name*](#def:name,qualified "6.5.5.1 General [basic.lookup.qual.general]") is

- [(2.3)](#2.3)

a member-qualified name or

- [(2.4)](#2.4)

the terminal name of
  * [(2.4.1)](#2.4.1)

a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]"),

  * [(2.4.2)](#2.4.2)

a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]"),

  * [(2.4.3)](#2.4.3)

a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]"),

  * [(2.4.4)](#2.4.4)

a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3 Namespace alias [namespace.alias]"), or

  * [(2.4.5)](#2.4.5)

a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"), or[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1 General [class.derived.general]") that has a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3 Qualified names"))[.](#2.sentence-2)

The [*lookup context*](#def:lookup_context "6.5.5.1 General [basic.lookup.qual.general]") of a member-qualified name is
the type of its associated object expression
(considered dependent if the object expression is type-dependent)[.](#2.sentence-3)

The lookup context of any other qualified name is
the type, template, or namespace
nominated by the preceding [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#2.sentence-4)

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

When parsing a class member access,
the name following the -> or . is
a qualified name even though it is not yet known of which kind[.](#2.sentence-5)

â *end note*]

[*Example [2](#example-2)*:

In N::C::m.Base::f()Base is a member-qualified name;
the other qualified names are C, m, and f[.](#2.sentence-6)

â *end example*]

[3](#3)

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

[*Qualified name lookup*](#def:lookup,qualified_name "6.5.5.1 General [basic.lookup.qual.general]") in a class, namespace, or enumeration performs
a search of the scope associated with it ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup"))
except as specified below[.](#3.sentence-1)

Unless otherwise specified,
a qualified name undergoes qualified name lookup in its lookup context
from the point where it appears
unless the lookup context either
is dependent and is not the current instantiation ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types")) or
is not a class or class template[.](#3.sentence-2)

If nothing is found by qualified lookup for a member-qualified name
that is the terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")) of
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and
is not dependent, it undergoes unqualified lookup[.](#3.sentence-3)

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

During lookup for a template specialization, no names are dependent[.](#3.sentence-4)

â *end note*]

[*Example [3](#example-3)*: int f();struct A {int B, C; template<int> using D = void; using T = void; void f();};using B = A;template<int> using C = A;template<int> using D = A;template<int> using X = A;

template<class T>void g(T *p) { // as instantiated for g<A>: p->X<0>::f(); // error: A​::​X not found in ((p->X) < 0) > ​::​f() p->template X<0>::f(); // OK, ​::​X found in definition context p->B::f(); // OK, non-type A​::​B ignored p->template C<0>::f(); // error: A​::​C is not a template p->template D<0>::f(); // error: A​::​D<0> is not a class type p->T::f(); // error: A​::​T is not a class type}template void g(A*); â *end example*]

[4](#4)

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

If a qualified name Q follows a ~:

- [(4.1)](#4.1)

  If Q is a member-qualified name,
it undergoes unqualified lookup as well as qualified lookup[.](#4.1.sentence-1)

- [(4.2)](#4.2)

  Otherwise, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") N shall nominate a type[.](#4.2.sentence-1)
  If N has another [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") S,Q is looked up as if its lookup context were that nominated by S[.](#4.2.sentence-2)

- [(4.3)](#4.3)

  Otherwise, if the terminal name of N is a member-qualified name M,Q is looked up as if ~Q appeared in place of M (as above)[.](#4.3.sentence-1)

- [(4.4)](#4.4)

  Otherwise, Q undergoes unqualified lookup[.](#4.4.sentence-1)

- [(4.5)](#4.5)

  Each lookup for Q considers only
types (if Q is not followed by a <) and
templates whose specializations are types[.](#4.5.sentence-1)
  If it finds nothing or is ambiguous, it is discarded[.](#4.5.sentence-2)

- [(4.6)](#4.6)

  The [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") that is or contains Q shall refer to its (original) lookup context (ignoring cv-qualification) under
the interpretation established by at least one (successful) lookup performed[.](#4.6.sentence-1)

[*Example [4](#example-4)*: struct C {typedef int I;};typedef int I1, I2;extern int* p;extern int* q;void f() { p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is found by unqualified lookup}struct A {~A();};typedef A AB;int main() { AB* p;
 p->AB::~AB(); // explicitly calls the destructor for A} â *end example*]
