Files
2025-10-25 03:02:53 +03:00

949 lines
55 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[basic.lookup]
# 6 Basics [[basic]](./#basic)
## 6.5 Name lookup [basic.lookup]
### [6.5.1](#general) General [[basic.lookup.general]](basic.lookup.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1624)
[*Name lookup*](#def:lookup,name "6.5.1General[basic.lookup.general]") associates the use of a name
with a set of declarations ([[basic.def]](basic.def "6.2Declarations and definitions")) of that name[.](#general-1.sentence-1)
The name lookup rules apply uniformly to all names (including[*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s* ([[dcl.typedef]](dcl.typedef "9.2.4The typedef specifier")),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]")*s* ([[basic.namespace]](basic.namespace "9.9Namespaces")), and[*class-name*](class.pre#nt:class-name "11.1Preamble[class.pre]")*s* ([[class.name]](class.name "11.3Class names"))) wherever the grammar allows
such names in the context discussed by a particular rule[.](#general-1.sentence-2)
Unless otherwise specified,
the program is ill-formed if no declarations are found[.](#general-1.sentence-3)
If the declarations found by name lookup
all denote functions or function templates,
the declarations are said to form an [*overload set*](#def:overload_set "6.5.1General[basic.lookup.general]")[.](#general-1.sentence-4)
Otherwise,
if the declarations found by name lookup do not all denote the same entity,they are [*ambiguous*](#def:ambiguous "6.5.1General[basic.lookup.general]") and the program is ill-formed[.](#general-1.sentence-5)
Overload resolution ([[over.match]](over.match "12.2Overload resolution"), [[over.over]](over.over "12.3Address of an overload set"))
takes place after name lookup has succeeded[.](#general-1.sentence-6)
The access rules ([[class.access]](class.access "11.8Member access control"))
are considered only once name lookup and
function overload resolution (if applicable) have succeeded[.](#general-1.sentence-7)
Only after
name lookup, function overload resolution (if applicable) and access
checking have succeeded
are the semantic properties introduced by the declarations
used in further processing[.](#general-1.sentence-8)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1650)
A program point P is said to follow
any declaration in the same translation unit
whose locus ([[basic.scope.pdecl]](basic.scope.pdecl "6.4.2Point of declaration")) is before P[.](#general-2.sentence-1)
[*Note [1](#general-note-1)*:
The declaration might appear in a scope that does not contain P[.](#general-2.sentence-2)
— *end note*]
A declaration X [*precedes*](#def:declaration,precede "6.5.1General[basic.lookup.general]") a program point P in a translation unit L if P follows X, X inhabits a class scope and is reachable from P, or
else X appears in a translation unit D and
- [(2.1)](#general-2.1)
P follows
a [*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]") or [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") that imports D (directly or indirectly), and
- [(2.2)](#general-2.2)
X appears after the [*module-declaration*](module.unit#nt:module-declaration "10.1Module units and purviews[module.unit]") in D (if any) and
before the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5Private module fragment[module.private.frag]") in D (if any), and
- [(2.3)](#general-2.3)
either X is exported or else D and L are part of the same module andX does not inhabit a namespace with internal linkage or
declare a name with internal linkage[.](#general-2.sentence-3)
[*Note [2](#general-note-2)*:
Names declared by a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]") have no linkage[.](#general-2.3.sentence-2)
— *end note*]
[*Note [3](#general-note-3)*:
A [*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]") imports both
the named translation unit(s) and
any modules named by exported[*module-import-declaration*](module.import#nt:module-import-declaration "10.3Import declaration[module.import]")*s* within them,
recursively[.](#general-2.sentence-4)
[*Example [1](#general-example-1)*:
Translation unit #1:export module Q;export int sq(int i) { return i*i; }
Translation unit #2:export module R;export import Q;
Translation unit #3:import R;int main() { return sq(9); } // OK, sq from module Q — *end example*]
— *end note*]
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1702)
A [*single search*](#def:search,single "6.5.1General[basic.lookup.general]") in a scope S for a name N from a program point P finds all declarations that precede P to which any name that is the same as N ([[basic.pre]](basic.pre "6.1Preamble")) is bound in S[.](#general-3.sentence-1)
If any such declaration is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") whose terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names"))
is not dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")),
it is replaced by the declarations named by
the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))[.](#general-3.sentence-2)
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1714)
In certain contexts, only certain kinds of declarations are included[.](#general-4.sentence-1)
After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found[.](#general-4.sentence-2)
[*Note [4](#general-note-4)*:
A type (but not a type alias or template)
is therefore hidden by any other entity in its scope[.](#general-4.sentence-3)
— *end note*]
However, if a lookup is [*type-only*](#def:lookup,type-only "6.5.1General[basic.lookup.general]"),
only declarations of
types and templates whose specializations are types are considered;
furthermore, if declarations
of a type alias and of its underlying entity are found,
the declaration of the type alias is discarded
instead of the type declaration[.](#general-4.sentence-4)
### [6.5.2](#class.member.lookup) Member name lookup [[class.member.lookup]](class.member.lookup)
[1](#class.member.lookup-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1735)
A [*search*](#def:search "6.5.2Member name lookup[class.member.lookup]") in a scope X for a name M from a program point P is a single search in X for M from P unless X is the scope of a class or class template T, in which case the
following steps define the result of the search[.](#class.member.lookup-1.sentence-1)
[*Note [1](#class.member.lookup-note-1)*:
The result differs only
if M is a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") or
if the single search would find nothing[.](#class.member.lookup-1.sentence-2)
— *end note*]
[2](#class.member.lookup-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1747)
The [*lookup set*](#def:lookup_set "6.5.2Member name lookup[class.member.lookup]") for a name N in a class or class template C, called S(N,C),
consists of two component sets:
the [*declaration set*](#def:declaration_set), a set of members named N; and
the [*subobject set*](#def:subobject_set),
a set of subobjects where declarations of these members were found
(possibly via [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")*s*)[.](#class.member.lookup-2.sentence-1)
In the declaration set, type declarations (including injected-class-names)
are replaced by the types they designate[.](#class.member.lookup-2.sentence-2)
S(N,C) is calculated as follows:
[3](#class.member.lookup-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1757)
The declaration set is the result of
a single search in the scope of C for N from immediately after the [*class-specifier*](class.pre#nt:class-specifier "11.1Preamble[class.pre]") of C if P is in a complete-class context of C or
from P otherwise[.](#class.member.lookup-3.sentence-1)
If the resulting declaration set is not empty, the subobject set
contains C itself, and calculation is complete[.](#class.member.lookup-3.sentence-2)
[4](#class.member.lookup-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1766)
Otherwise (i.e., C does not contain a declaration of N or the resulting declaration set is empty), S(N,C) is initially empty[.](#class.member.lookup-4.sentence-1)
Calculate the lookup set for N in each direct non-dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")) base class subobject Bi, and
merge each such lookup set S(N,Bi) in turn into S(N,C)[.](#class.member.lookup-4.sentence-2)
[*Note [2](#class.member.lookup-note-2)*:
If C is incomplete,
only base classes whose [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1General[class.derived.general]") appears before P are considered[.](#class.member.lookup-4.sentence-3)
If C is an instantiated class, its base classes are not dependent[.](#class.member.lookup-4.sentence-4)
— *end note*]
[5](#class.member.lookup-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1779)
The following steps define the result of merging lookup set S(N,Bi) into the intermediate S(N,C):
- [(5.1)](#class.member.lookup-5.1)
If each of the subobject members of S(N,Bi) is a base class
subobject of at least one of the subobject members of S(N,C), or ifS(N,Bi) is empty, S(N,C) is unchanged and the merge is complete[.](#class.member.lookup-5.1.sentence-1)
Conversely, if each of the subobject members of S(N,C) is a base class
subobject of at least one of the subobject members of S(N,Bi), or ifS(N,C) is empty, the new S(N,C) is a copy of S(N,Bi)[.](#class.member.lookup-5.1.sentence-2)
- [(5.2)](#class.member.lookup-5.2)
Otherwise, if the declaration sets of S(N,Bi) and S(N,C) differ, the merge is ambiguous: the new S(N,C) is a lookup set with an
invalid declaration set and the union of the subobject sets[.](#class.member.lookup-5.2.sentence-1)
In
subsequent merges, an invalid declaration set is considered different
from any other[.](#class.member.lookup-5.2.sentence-2)
- [(5.3)](#class.member.lookup-5.3)
Otherwise, the new S(N,C) is a lookup set with the shared set of
declarations and the union of the subobject sets[.](#class.member.lookup-5.3.sentence-1)
[6](#class.member.lookup-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1801)
The result of the search is the declaration set of S(M,T)[.](#class.member.lookup-6.sentence-1)
If it is an invalid set, the program is ill-formed[.](#class.member.lookup-6.sentence-2)
If it differs from the result of a search in T for M in a complete-class context ([[class.mem]](class.mem "11.4Class members")) of T,
the program is ill-formed, no diagnostic required[.](#class.member.lookup-6.sentence-3)
[*Example [1](#class.member.lookup-example-1)*: struct A { int x; }; // S(x,A) = { { A::x }, { A } }struct B { float x; }; // S(x,B) = { { B::x }, { B } }struct C: public A, public B { }; // S(x,C) = { invalid, { A in C, B in C } }struct D: public virtual C { }; // S(x,D) = S(x,C)struct E: public virtual C { char x; }; // S(x,E) = { { E::x }, { E } }struct F: public D, public E { }; // S(x,F) = S(x,E)int main() { F f;
f.x = 0; // OK, lookup finds E::x}
S(x,F) is unambiguous because the A and B base
class subobjects of D are also base class subobjects of E, soS(x,D) is discarded in the first merge step[.](#class.member.lookup-6.sentence-4)
— *end example*]
[7](#class.member.lookup-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1826)
If M is a non-dependent [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]"),
conversion function templates that are members of T are considered[.](#class.member.lookup-7.sentence-1)
For each such template F, the lookup set S(t,T) is constructed,
considering a function template declaration to have the name t only if it corresponds to a declaration of F ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))[.](#class.member.lookup-7.sentence-2)
The members of the declaration set of each such lookup set,
which shall not be an invalid set, are included in the result[.](#class.member.lookup-7.sentence-3)
[*Note [3](#class.member.lookup-note-3)*:
Overload resolution will discard those
that cannot convert to the type specified by M ([[temp.over]](temp.over "13.10.4Overload resolution"))[.](#class.member.lookup-7.sentence-4)
— *end note*]
[8](#class.member.lookup-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1839)
[*Note [4](#class.member.lookup-note-4)*:
A static member, a nested type or an enumerator defined in a base classT can unambiguously be found even if an object has more than one
base class subobject of type T[.](#class.member.lookup-8.sentence-1)
Two base class subobjects share
the non-static member subobjects of their common virtual base classes[.](#class.member.lookup-8.sentence-2)
— *end note*]
[*Example [2](#class.member.lookup-example-2)*: struct V {int v;};struct A {int a; static int s; enum { e };};struct B : A, virtual V { };struct C : A, virtual V { };struct D : B, C { };
void f(D* pd) { pd->v++; // OK, only one v (virtual) pd->s++; // OK, only one s (static)int i = pd->e; // OK, only one e (enumerator) pd->a++; // error: ambiguous: two as in D} — *end example*]
[9](#class.member.lookup-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1869)
[*Note [5](#class.member.lookup-note-5)*:
When virtual base classes are used, a hidden declaration can be reached
along a path through the subobject lattice that does not pass through
the hiding declaration[.](#class.member.lookup-9.sentence-1)
This is not an ambiguity[.](#class.member.lookup-9.sentence-2)
The identical use with
non-virtual base classes is an ambiguity; in that case there is no
unique instance of the name that hides all the others[.](#class.member.lookup-9.sentence-3)
— *end note*]
[*Example [3](#class.member.lookup-example-3)*: struct V { int f(); int x; };struct W { int g(); int y; };struct B : virtual V, W {int f(); int x; int g(); int y;};struct C : virtual V, W { };
struct D : B, C { void glorp(); };
![SVG Image](data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwLjAwIDAuMDAgMzg2LjAwIDE0MC4wMCIgd2lkdGg9IjM4NnB0IiBoZWlnaHQ9IjE0MHB0Ij4KPGcgY2xhc3M9ImdyYXBoIj4KdmlydAoKPGcgY2xhc3M9Im5vZGUiPgpXMQpXCjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KVgpWCjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KVzIKVwo8L2c+Cgo8ZyBjbGFzcz0ibm9kZSI+CkIKQgo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkItJmd0O1cxCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iYmxhY2siIGQ9Ik05NC4yNiwtNzYuMTZDODEuODUsLTg0LjQzIDYzLjM3LC05Ni43NSA0OC45MiwtMTA2LjM4IiAvPgo8cG9seWdvbiBmaWxsPSJibGFjayIgc3Ryb2tlPSJibGFjayIgLz4KPC9nPgoKPGcgY2xhc3M9ImVkZ2UiPgpCLSZndDtWCjxwYXRoIHN0cm9rZT0iYmxhY2siIGZpbGw9Im5vbmUiIGQ9Ik0xMjEuNzQsLTc2LjE2QzEzNC4xNSwtODQuNDMgMTUyLjYzLC05Ni43NSAxNjcuMDgsLTEwNi4zOCIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KQwpDCjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KQy0mZ3Q7Vgo8cGF0aCBmaWxsPSJub25lIiBkPSJNMjU2LjI2LC03Ni4xNkMyNDMuODUsLTg0LjQzIDIyNS4zNywtOTYuNzUgMjEwLjkyLC0xMDYuMzgiIHN0cm9rZT0iYmxhY2siIC8+Cjxwb2x5Z29uIGZpbGw9ImJsYWNrIiBzdHJva2U9ImJsYWNrIiAvPgo8L2c+Cgo8ZyBjbGFzcz0iZWRnZSI+CkMtJmd0O1cyCjxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0yODMuNzQsLTc2LjE2QzI5Ni4xNSwtODQuNDMgMzE0LjYzLC05Ni43NSAzMjkuMDgsLTEwNi4zOCIgc3Ryb2tlPSJibGFjayIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJub2RlIj4KRApECjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KRC0mZ3Q7Qgo8cGF0aCBzdHJva2U9ImJsYWNrIiBmaWxsPSJub25lIiBkPSJNMTc1LjI2LC0yMC4xNkMxNjIuODUsLTI4LjQzIDE0NC4zNywtNDAuNzUgMTI5LjkyLC01MC4zOCIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KCjxnIGNsYXNzPSJlZGdlIj4KRC0mZ3Q7Qwo8cGF0aCBzdHJva2U9ImJsYWNrIiBkPSJNMjAyLjc0LC0yMC4xNkMyMTUuMTUsLTI4LjQzIDIzMy42MywtNDAuNzUgMjQ4LjA4LC01MC4zOCIgZmlsbD0ibm9uZSIgLz4KPHBvbHlnb24gZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIC8+CjwvZz4KPC9nPgo8L3N2Zz4=)
Figure [1](#fig:class.lookup) — Name lookup [[fig:class.lookup]](./fig:class.lookup)
As illustrated in Figure [1](#fig:class.lookup),
the names declared in V and the left-hand instance of W are hidden by those in B, but the names declared in the
right-hand instance of W are not hidden at all[.](#class.member.lookup-9.sentence-4)
void D::glorp() { x++; // OK, B::x hides V::x f(); // OK, B::f() hides V::f() y++; // error: B::y and C's W::y g(); // error: B::g() and C's W::g()} — *end example*]
[10](#class.member.lookup-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1912)
An explicit or implicit conversion from a pointer to or
an expression designating an object
of a
derived class to a pointer or reference to one of its base classes shall
unambiguously refer to a unique object representing the base class[.](#class.member.lookup-10.sentence-1)
[*Example [4](#class.member.lookup-example-4)*: struct V { };struct A { };struct B : A, virtual V { };struct C : A, virtual V { };struct D : B, C { };
void g() { D d;
B* pb = &d;
A* pa = &d; // error: ambiguous: C's A or B's A? V* pv = &d; // OK, only one V subobject} — *end example*]
[11](#class.member.lookup-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1935)
[*Note [6](#class.member.lookup-note-6)*:
Even if the result of name lookup is unambiguous, use of a name found in
multiple subobjects might still be
ambiguous ([[conv.mem]](conv.mem "7.3.13Pointer-to-member conversions"), [[expr.ref]](expr.ref "7.6.1.5Class member access"), [[class.access.base]](class.access.base "11.8.3Accessibility of base classes and base class members"))[.](#class.member.lookup-11.sentence-1)
— *end note*]
[*Example [5](#class.member.lookup-example-5)*: struct B1 {void f(); static void f(int); int i;};struct B2 {void f(double);};struct I1: B1 { };struct I2: B1 { };
struct D: I1, I2, B2 {using B1::f; using B2::f; void g() { f(); // Ambiguous conversion of this f(0); // Unambiguous (static) f(0.0); // Unambiguous (only one B2)int B1::* mpB1 = &D::i; // Unambiguousint D::* mpD = &D::i; // Ambiguous conversion}}; — *end example*]
### [6.5.3](#unqual) Unqualified name lookup [[basic.lookup.unqual]](basic.lookup.unqual)
[1](#unqual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1972)
A [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") is[*active*](#def:active) in a scope S at a program point P if it precedes P and inhabits either S or
the scope of a namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that is active in S at P[.](#unqual-1.sentence-1)
[2](#unqual-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L1979)
An [*unqualified search*](#def:unqualified_search) in a scope S from a program point P includes the results of searches from P in
- [(2.1)](#unqual-2.1)
S, and
- [(2.2)](#unqual-2.2)
for any scope U that contains P and is or is contained by S,
each namespace contained by S that is nominated by
a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that is active in U at P[.](#unqual-2.sentence-1)
If no declarations are found,
the results of the unqualified search are
the results of an unqualified search in the parent scope of S, if any,
from P[.](#unqual-2.sentence-2)
[*Note [1](#unqual-note-1)*:
When a class scope is searched,
the scopes of its base classes are also searched ([[class.member.lookup]](#class.member.lookup "6.5.2Member name lookup"))[.](#unqual-2.sentence-3)
If it inherits from a single base,
it is as if the scope of the base immediately contains
the scope of the derived class[.](#unqual-2.sentence-4)
Template parameter scopes
that are associated with one scope in the chain of parents
are also considered ([[temp.local]](temp.local "13.8.2Locally declared names"))[.](#unqual-2.sentence-5)
— *end note*]
[3](#unqual-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2005)
[*Unqualified name lookup*](#def:lookup,unqualified_name "6.5.3Unqualified name lookup[basic.lookup.unqual]") from a program point performs an unqualified search in its immediate scope[.](#unqual-3.sentence-1)
[4](#unqual-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2009)
An [*unqualified name*](#def:name,unqualified "6.5.3Unqualified name lookup[basic.lookup.unqual]") is a name
that does not immediately follow a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") or
the . or -> in a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access")),
possibly after a template keyword or ~[.](#unqual-4.sentence-1)
Unless otherwise specified,
such a name undergoes unqualified name lookup from the point where it appears[.](#unqual-4.sentence-2)
[5](#unqual-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2017)
An unqualified name that is a component name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2Unqualified names")) of
a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1General[dcl.type.general]") or [*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1General[dcl.decl.general]") of
a [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3Conversion functions[class.conv.fct]") is looked up in the same fashion
as the [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") in which it appears[.](#unqual-5.sentence-1)
If that lookup finds nothing, it undergoes unqualified name lookup;
in each case, only names
that denote types or templates whose specializations are types are considered[.](#unqual-5.sentence-2)
[*Example [1](#unqual-example-1)*: struct T1 { struct U { int i; }; };struct T2 { };struct U1 {};struct U2 {};
struct B {using T = T1; using U = U1; operator U1 T1::*(); operator U1 T2::*(); operator U2 T1::*(); operator U2 T2::*();};
template<class X, class T>int g() {using U = U2;
X().operator U T::*(); // #1, searches for T in the scope of X first X().operator U decltype(T())::*(); // #2return 0;}int x = g<B, T2>(); // #1 calls B::operator U1 T1::*// #2 calls B::operator U1 T2::* — *end example*]
[6](#unqual-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2053)
In a friend declaration [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") whose lookup context ([[basic.lookup.qual]](#qual "6.5.5Qualified name lookup")) is a class or namespace S,
lookup for an unqualified name
that appears after the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") performs a search in the scope associated with S[.](#unqual-6.sentence-1)
If that lookup finds nothing, it undergoes unqualified name lookup[.](#unqual-6.sentence-2)
[*Example [2](#unqual-example-2)*: using I = int;using D = double;namespace A {inline namespace N {using C = char; }using F = float; void f(I); void f(D); void f(C); void f(F);}struct X0 {using F = float; };struct W {using D = void; struct X : X0 {void g(I); void g(::D); void g(F); };};namespace B {typedef short I, F; class Y {friend void A::f(I); // error: no void A::f(short)friend void A::f(D); // OKfriend void A::f(C); // error: A::N::C not foundfriend void A::f(F); // OKfriend void W::X::g(I); // error: no void X::g(short)friend void W::X::g(D); // OKfriend void W::X::g(F); // OK};} — *end example*]
### [6.5.4](#argdep) Argument-dependent name lookup [[basic.lookup.argdep]](basic.lookup.argdep)
[1](#argdep-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2100)
When the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") in
a function call ([[expr.call]](expr.call "7.6.1.3Function call")) is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]"),
and unqualified lookup ([[basic.lookup.unqual]](#unqual "6.5.3Unqualified name lookup"))
for the name in the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") does not find any
- [(1.1)](#argdep-1.1)
declaration of a class member, or
- [(1.2)](#argdep-1.2)
function declaration inhabiting a block scope, or
- [(1.3)](#argdep-1.3)
declaration not of a function or function template
then lookup for the name also includes the result of[*argument-dependent lookup*](#def:lookup,argument-dependent "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") in a set of associated namespaces
that depends on the types of the arguments
(and for type template template arguments, the namespace of the template argument),
as specified below[.](#argdep-1.sentence-1)
[*Example [1](#argdep-example-1)*: namespace N {struct S { }; void f(S);}void g() { N::S s;
f(s); // OK, calls N::f(f)(s); // error: N::f not considered; parentheses prevent argument-dependent lookup} — *end example*]
[2](#argdep-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2133)
[*Note [1](#argdep-note-1)*:
For purposes of determining
(during parsing) whether an expression is a[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1General[expr.post.general]") for a function call, the usual name lookup
rules apply[.](#argdep-2.sentence-1)
In some cases
a name followed by < is treated as a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") even though name lookup did not find a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") (see [[temp.names]](temp.names "13.3Names of template specializations"))[.](#argdep-2.sentence-2)
For example,int h;void g();namespace N {struct A {}; template <class T> int f(T); template <class T> int g(T); template <class T> int h(T);}int x = f<N::A>(N::A()); // OK, lookup of f finds nothing, f treated as template nameint y = g<N::A>(N::A()); // OK, lookup of g finds a function, g treated as template nameint z = h<N::A>(N::A()); // error: h< does not begin a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]")
The rules have no effect on the syntactic interpretation of an expression[.](#argdep-2.sentence-4)
For example,typedef int f;namespace N {struct A {friend void f(A &); operator int(); void g(A a) {int i = f(a); // f is the typedef, not the friend function: equivalent to int(a)}};}
Because the expression is not a function call,
argument-dependent name lookup does not apply and
the friend function f is not found[.](#argdep-2.sentence-6)
— *end note*]
[3](#argdep-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2178)
For each argument type T in the function call,
there is a set of zero or more [*associated entities*](#def:entity,associated "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") to be considered[.](#argdep-3.sentence-1)
The set of entities is determined entirely by
the types of the function arguments
(and any type template template arguments)[.](#argdep-3.sentence-2)
Any [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The typedef specifier[dcl.typedef]")*s* and [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")*s* used to specify the types
do not contribute to this set[.](#argdep-3.sentence-3)
The set of entities
is determined in the following way:
- [(3.1)](#argdep-3.1)
If T is std::meta::info ([[meta.syn]](meta.syn "21.4.1Header <meta> synopsis")),
its associated set of entities is the singleton containing
the enumeration type std::meta::operators ([[meta.reflection.operators]](meta.reflection.operators "21.4.5Operator representations"))[.](#argdep-3.1.sentence-1)
[*Note [2](#argdep-note-2)*:
The std::meta::info type is a type alias,
so an explicit rule is needed to associate calls
whose arguments are reflections with the namespace std::meta[.](#argdep-3.1.sentence-2)
— *end note*]
- [(3.2)](#argdep-3.2)
If T is any other fundamental type, its associated set of
entities is empty[.](#argdep-3.2.sentence-1)
- [(3.3)](#argdep-3.3)
If T is a class type (including unions),
its associated entities are:
the class itself;
the class of which it is a member, if any;
and, if it is a complete type, its direct and indirect base classes[.](#argdep-3.3.sentence-1)
Furthermore, if T is a class template specialization,
its associated entities also include:
the entities
associated with the types of the template arguments
provided for template type parameters;
the templates used as type template template arguments; and
the classes of which any member templates used as type template template
arguments are members[.](#argdep-3.3.sentence-2)
[*Note [3](#argdep-note-3)*:
Constant template arguments,
variable template template arguments, and
concept template arguments
do not
contribute to the set of associated entities[.](#argdep-3.3.sentence-3)
— *end note*]
- [(3.4)](#argdep-3.4)
If T is an enumeration type,
its associated entities are T and, if it is a class member, the member's class[.](#argdep-3.4.sentence-1)
- [(3.5)](#argdep-3.5)
If T is a pointer to U or an array of U,
its associated entities are those associated with U[.](#argdep-3.5.sentence-1)
- [(3.6)](#argdep-3.6)
If T is a function type, its associated
entities are those associated with the function parameter types and those
associated with the return type[.](#argdep-3.6.sentence-1)
- [(3.7)](#argdep-3.7)
If T is a pointer to a member function of a classX, its associated entities are those associated
with the function parameter types and return type, together with those
associated with X[.](#argdep-3.7.sentence-1)
- [(3.8)](#argdep-3.8)
If T is a pointer to a data member of class X, its
associated entities are those associated with the member
type together with those associated with X[.](#argdep-3.8.sentence-1)
In addition, if the argument is an overload set or the address of such a set,
its associated entities
are the union of those associated with each of the
members of the set, i.e., the entities associated with its
parameter types and return type[.](#argdep-3.sentence-5)
Additionally, if the aforementioned overload set is named with
a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"), its associated entities also include
its template template arguments and
those associated with its type template arguments[.](#argdep-3.sentence-6)
[4](#argdep-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2254)
The [*associated namespaces*](#def:associated_namespaces) for a call are
the innermost enclosing non-inline namespaces for its associated entities
as well as every element of the inline namespace set ([[namespace.def]](namespace.def "9.9.2Namespace definition"))
of those namespaces[.](#argdep-4.sentence-1)
Argument-dependent lookup finds
all declarations of functions and function templates that
- [(4.1)](#argdep-4.1)
are found by a search of any associated namespace, or
- [(4.2)](#argdep-4.2)
are declared as a friend ([[class.friend]](class.friend "11.8.4Friends")) of any class
with a reachable definition in the set of associated entities, or
- [(4.3)](#argdep-4.3)
are exported,
are attached to a named module M ([[module.interface]](module.interface "10.2Export declaration")),
do not appear in the translation unit containing the point of the lookup, and
have the same innermost enclosing non-inline namespace scope as
a declaration of an associated entity attached to M ([[basic.link]](basic.link "6.7Program and linkage"))[.](#argdep-4.sentence-2)
If the lookup is for a dependent name ([[temp.dep]](temp.dep "13.8.3Dependent names"), [[temp.dep.candidate]](temp.dep.candidate "13.8.4.2Candidate functions")),
the above lookup is also performed
from each point in the instantiation context ([[module.context]](module.context "10.6Instantiation context")) of the lookup,
additionally ignoring any declaration that
appears in another translation unit,
is attached to the global module, and
is either discarded ([[module.global.frag]](module.global.frag "10.4Global module fragment")) or has internal linkage[.](#argdep-4.sentence-3)
[5](#argdep-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2282)
[*Example [2](#argdep-example-2)*:
Translation unit #1:export module M;namespace R {export struct X {}; export void f(X);}namespace S {export void f(R::X, R::X);}
Translation unit #2:export module N;import M;export R::X make();namespace R { static int g(X); }export template<typename T, typename U> void apply(T t, U u) { f(t, u);
g(t);}
Translation unit #3:module Q;import N;namespace S {struct Z { template<typename T> operator T(); };}void test() {auto x = make(); // OK, decltype(x) is R::X in module M R::f(x); // error: R and R::f are not visible here f(x); // OK, calls R::f from interface of M f(x, S::Z()); // error: S::f in module M not considered// even though S is an associated namespace apply(x, S::Z()); // error: S::f is visible in instantiation context, but// R::g has internal linkage and cannot be used outside TU #2} — *end example*]
[6](#argdep-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2324)
[*Note [4](#argdep-note-4)*:
The associated namespace can include namespaces
already considered by ordinary unqualified lookup[.](#argdep-6.sentence-1)
— *end note*]
[*Example [3](#argdep-example-3)*: namespace NS {class T { }; void f(T); void g(T, int);} NS::T parm;void g(NS::T, float);int main() { f(parm); // OK, calls NS::fextern void g(NS::T, float);
g(parm, 1); // OK, calls g(NS::T, float)} — *end example*]
### [6.5.5](#qual) Qualified name lookup [[basic.lookup.qual]](basic.lookup.qual)
#### [6.5.5.1](#qual.general) General [[basic.lookup.qual.general]](basic.lookup.qual.general)
[1](#qual.general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2350)
Lookup of an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") followed by a :: scope resolution operator
considers only
namespaces, types, and templates whose specializations are types[.](#qual.general-1.sentence-1)
If a
name,[*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"),[*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), or[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3Simple 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.3Qualified names[expr.prim.id.qual]") ([[temp.dep.splice]](temp.dep.splice "13.8.3.5Dependent 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.3Qualified names[expr.prim.id.qual]")[.](#qual.general-1.sentence-2)
[*Example [1](#qual.general-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](#qual.general-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.2Unqualified names")), if any, of
- [(2.1)](#qual.general-2.1)
an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") or
- [(2.2)](#qual.general-2.2)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") of the form[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]") :: or [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") ::
in the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1General[expr.prim.id.general]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5Class member access"))[.](#qual.general-2.sentence-1)
A [*qualified name*](#def:name,qualified "6.5.5.1General[basic.lookup.qual.general]") is
- [(2.3)](#qual.general-2.3)
a member-qualified name or
- [(2.4)](#qual.general-2.4)
the terminal name of
* [(2.4.1)](#qual.general-2.4.1)
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]"),
* [(2.4.2)](#qual.general-2.4.2)
a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]"),
* [(2.4.3)](#qual.general-2.4.3)
a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1General[temp.res.general]"),
* [(2.4.4)](#qual.general-2.4.4)
a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3Namespace alias[namespace.alias]"), or
* [(2.4.5)](#qual.general-2.4.5)
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"),[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10The reflection operator[expr.reflect]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]"), or[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1General[class.derived.general]") that has a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3Qualified names"))[.](#qual.general-2.sentence-2)
The [*lookup context*](#def:lookup_context "6.5.5.1General[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)[.](#qual.general-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.3Qualified names[expr.prim.id.qual]")[.](#qual.general-2.sentence-4)
[*Note [1](#qual.general-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[.](#qual.general-2.sentence-5)
— *end note*]
[*Example [2](#qual.general-example-2)*:
In N::C::m.Base::f()Base is a member-qualified name;
the other qualified names are C, m, and f[.](#qual.general-2.sentence-6)
— *end example*]
[3](#qual.general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2440)
[*Qualified name lookup*](#def:lookup,qualified_name "6.5.5.1General[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.2Member name lookup"))
except as specified below[.](#qual.general-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.2Dependent types")) or
is not a class or class template[.](#qual.general-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.2Unqualified names")) of
a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") and
is not dependent, it undergoes unqualified lookup[.](#qual.general-3.sentence-3)
[*Note [2](#qual.general-note-2)*:
During lookup for a template specialization, no names are dependent[.](#qual.general-3.sentence-4)
— *end note*]
[*Example [3](#qual.general-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](#qual.general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2485)
If a qualified name Q follows a ~:
- [(4.1)](#qual.general-4.1)
If Q is a member-qualified name,
it undergoes unqualified lookup as well as qualified lookup[.](#qual.general-4.1.sentence-1)
- [(4.2)](#qual.general-4.2)
Otherwise, its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") N shall nominate a type[.](#qual.general-4.2.sentence-1)
If N has another [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") S,Q is looked up as if its lookup context were that nominated by S[.](#qual.general-4.2.sentence-2)
- [(4.3)](#qual.general-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)[.](#qual.general-4.3.sentence-1)
- [(4.4)](#qual.general-4.4)
Otherwise, Q undergoes unqualified lookup[.](#qual.general-4.4.sentence-1)
- [(4.5)](#qual.general-4.5)
Each lookup for Q considers only
types (if Q is not followed by a <) and
templates whose specializations are types[.](#qual.general-4.5.sentence-1)
If it finds nothing or is ambiguous, it is discarded[.](#qual.general-4.5.sentence-2)
- [(4.6)](#qual.general-4.6)
The [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple 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[.](#qual.general-4.6.sentence-1)
[*Example [4](#qual.general-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*]
#### [6.5.5.2](#class.qual) Class members [[class.qual]](class.qual)
[1](#class.qual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2537)
In a lookup for a qualified name N whose lookup context is a class C in which function names are not ignored,[18](#footnote-18 "Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.")
- [(1.1)](#class.qual-1.1)
if the search finds the injected-class-name of C ([[class.pre]](class.pre "11.1Preamble")), or
- [(1.2)](#class.qual-1.2)
if N is dependent and
is the terminal name of a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration"))
that names a constructor,
N is instead considered to name the constructor of class C[.](#class.qual-1.sentence-1)
Such a constructor name shall be used only
in the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") of a (friend) declaration of a constructor or
in a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10The using declaration[namespace.udecl]")[.](#class.qual-1.sentence-2)
[*Example [1](#class.qual-example-1)*: struct A { A(); };struct B: public A { B(); };
A::A() { } B::B() { } B::A ba; // object of type A A::A a; // error: A::A is not a type namestruct A::A a2; // object of type A — *end example*]
[18)](#footnote-18)[18)](#footnoteref-18)
Lookups in which
function names are ignored include names appearing in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]"), an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]"), or a [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1General[class.derived.general]")[.](#footnote-18.sentence-1)
#### [6.5.5.3](#namespace.qual) Namespace members [[namespace.qual]](namespace.qual)
[1](#namespace.qual-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2574)
Qualified name lookup in a namespace N additionally searches
every element of the inline namespace set of N ([[namespace.def]](namespace.def "9.9.2Namespace definition"))[.](#namespace.qual-1.sentence-1)
If nothing is found,
the results of the lookup are the results of qualified name lookup
in each namespace nominated by a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that precedes the point of the lookup and
inhabits N or an element of N's inline namespace set[.](#namespace.qual-1.sentence-2)
[*Note [1](#namespace.qual-note-1)*:
If a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") refers to a namespace
that has already been considered, it does not affect the result[.](#namespace.qual-1.sentence-3)
— *end note*]
[*Example [1](#namespace.qual-example-1)*: int x;namespace Y {void f(float); void h(int);}namespace Z {void h(double);}namespace A {using namespace Y; void f(int); void g(int); int i;}namespace B {using namespace Z; void f(char); int i;}namespace AB {using namespace A; using namespace B; void g();}void h(){ AB::g(); // g is declared directly in AB, therefore S is { AB::g() } and AB::g() is chosen AB::f(1); // f is not declared directly in AB so the rules are applied recursively to A and B;// namespace Y is not searched and Y::f(float) is not considered;// S is { A::f(int), B::f(char) } and overload resolution chooses A::f(int) AB::f('c'); // as above but resolution chooses B::f(char) AB::x++; // x is not declared directly in AB, and is not declared in A or B, so the rules// are applied recursively to Y and Z, S is { } so the program is ill-formed AB::i++; // i is not declared directly in AB so the rules are applied recursively to A and B,// S is { A::i, B::i } so the use is ambiguous and the program is ill-formed AB::h(16.8); // h is not declared directly in AB and not declared directly in A or B so the rules// are applied recursively to Y and Z, S is { Y::h(int), Z::h(double) } and// overload resolution chooses Z::h(double)} — *end example*]
[2](#namespace.qual-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2640)
[*Note [2](#namespace.qual-note-2)*:
The same declaration found more than once is not an ambiguity (because
it is still a unique declaration)[.](#namespace.qual-2.sentence-1)
[*Example [2](#namespace.qual-example-2)*: namespace A {int a;}namespace B {using namespace A;}namespace C {using namespace A;}namespace BC {using namespace B; using namespace C;}void f(){ BC::a++; // OK, S is { A::a, A::a }}namespace D {using A::a;}namespace BD {using namespace B; using namespace D;}void g(){ BD::a++; // OK, S is { A::a, A::a }} — *end example*]
— *end note*]
[3](#namespace.qual-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2685)
[*Example [3](#namespace.qual-example-3)*:
Because each referenced namespace is searched at most once, the
following is well-defined:namespace B {int b;}namespace A {using namespace B; int a;}namespace B {using namespace A;}void f(){ A::a++; // OK, a declared directly in A, S is { A::a } B::a++; // OK, both A and B searched (once), S is { A::a } A::b++; // OK, both A and B searched (once), S is { B::b } B::b++; // OK, b declared directly in B, S is { B::b }}
— *end example*]
[4](#namespace.qual-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2713)
[*Note [3](#namespace.qual-note-3)*:
Class and enumeration declarations are not discarded
because of other declarations found in other searches[.](#namespace.qual-4.sentence-1)
— *end note*]
[*Example [4](#namespace.qual-example-4)*: namespace A {struct x { }; int x; int y;}namespace B {struct y { };}namespace C {using namespace A; using namespace B; int i = C::x; // OK, A::x (of type int)int j = C::y; // ambiguous, A::y or B::y} — *end example*]
### [6.5.6](#elab) Elaborated type specifiers [[basic.lookup.elab]](basic.lookup.elab)
[1](#elab-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2745)
If the [*class-key*](class.pre#nt:class-key "11.1Preamble[class.pre]") or enum keyword
in an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is followed by an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") that is not followed by ::,
lookup for the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is type-only ([[basic.lookup.general]](#general "6.5.1General"))[.](#elab-1.sentence-1)
[*Note [1](#elab-note-1)*:
In general, the recognition of an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") depends on the following tokens[.](#elab-1.sentence-2)
If the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is followed by ::,
see [[basic.lookup.qual]](#qual "6.5.5Qualified name lookup")[.](#elab-1.sentence-3)
— *end note*]
[2](#elab-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2758)
If the terminal name of the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is a qualified name,
lookup for it is type-only[.](#elab-2.sentence-1)
If the name lookup does not find a previously declared [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]"),
the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") is ill-formed[.](#elab-2.sentence-2)
[3](#elab-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2765)
[*Example [1](#elab-example-1)*: struct Node {struct Node* Next; // OK, refers to injected-class-name Nodestruct Data* Data; // OK, declares type Data at global scope and member Data};
struct Data {struct Node* Node; // OK, refers to Node at global scopefriend struct ::Glob; // error: Glob is not declared, cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))friend struct Glob; // OK, refers to (as yet) undeclared Glob at global scope./* ... */};
struct Base {struct Data; // OK, declares nested Datastruct ::Data* thatData; // OK, refers to ::Datastruct Base::Data* thisData; // OK, refers to nested Datafriend class ::Data; // OK, global Data is a friendfriend class Data; // OK, nested Data is a friendstruct Data { /* ... */ }; // Defines nested Data};
struct Data; // OK, redeclares Data at global scopestruct ::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))struct Base::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5Elaborated type specifiers"))struct Base::Datum; // error: Datum undefinedstruct Base::Data* pBase; // OK, refers to nested Data — *end example*]
### [6.5.7](#udir) Using-directives and namespace aliases [[basic.lookup.udir]](basic.lookup.udir)
[1](#udir-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L2800)
In a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") or [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3Namespace alias[namespace.alias]"),
during the lookup for a [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") or for a name in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") only namespace names are considered[.](#udir-1.sentence-1)