[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.1 General [basic.lookup.general]") associates the use of a name with a set of declarations ([[basic.def]](basic.def "6.2 Declarations 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.4 The typedef specifier [dcl.typedef]")*s* ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier")),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]")*s* ([[basic.namespace]](basic.namespace "9.9 Namespaces")), and[*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]")*s* ([[class.name]](class.name "11.3 Class 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.1 General [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.1 General [basic.lookup.general]") and the program is ill-formed[.](#general-1.sentence-5) Overload resolution ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set")) takes place after name lookup has succeeded[.](#general-1.sentence-6) The access rules ([[class.access]](class.access "11.8 Member 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.2 Point 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.1 General [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.3 Import declaration [module.import]") or [*module-declaration*](module.unit#nt:module-declaration "10.1 Module 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.1 Module units and purviews [module.unit]") in D (if any) and before the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private 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.10 The 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.3 Import 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.3 Import 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.1 General [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.1 Preamble")) is bound in S[.](#general-3.sentence-1) If any such declaration is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") whose terminal name ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names")) is not dependent ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types")), it is replaced by the declarations named by the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The 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.1 General [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.2 Member 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.3 Conversion 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.2 Member 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.10 The 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.1 Preamble [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.2 Dependent 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.1 General [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.4 Class 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.3 Conversion 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.1 General"))[.](#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.4 Overload 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.13 Pointer-to-member conversions"), [[expr.ref]](expr.ref "7.6.1.5 Class member access"), [[class.access.base]](class.access.base "11.8.3 Accessibility 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.4 Using 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.4 Using 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.4 Using 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.2 Member 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.2 Locally 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.3 Unqualified 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.3 Unqualified 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.3 Qualified names [expr.prim.id.qual]") or the . or -> in a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class 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.2 Unqualified names")) of a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1 General [dcl.type.general]") or [*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1 General [dcl.decl.general]") of a [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3 Conversion 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.3 Conversion 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::*();}; templateint 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(); // #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.1 General [dcl.decl.general]") whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") whose lookup context ([[basic.lookup.qual]](#qual "6.5.5 Qualified 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.1 General [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.1 General [expr.post.general]") in a function call ([[expr.call]](expr.call "7.6.1.3 Function call")) is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]"), and unqualified lookup ([[basic.lookup.unqual]](#unqual "6.5.3 Unqualified name lookup")) for the name in the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified 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.4 Argument-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.1 General [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.3 Names of template specializations [temp.names]") even though name lookup did not find a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") (see [[temp.names]](temp.names "13.3 Names of template specializations"))[.](#argdep-2.sentence-2) For example,int h;void g();namespace N {struct A {}; template int f(T); template int g(T); template int h(T);}int x = f(N::A()); // OK, lookup of f finds nothing, f treated as template nameint y = g(N::A()); // OK, lookup of g finds a function, g treated as template nameint z = h(N::A()); // error: h< does not begin a [*template-id*](temp.names#nt:template-id "13.3 Names 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.4 Argument-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.4 The typedef specifier [dcl.typedef]")*s* and [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The 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.1 Header synopsis")), its associated set of entities is the singleton containing the enumeration type std​::​meta​::​operators ([[meta.reflection.operators]](meta.reflection.operators "21.4.5 Operator 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.3 Names 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.2 Namespace 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.4 Friends")) 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.2 Export 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.7 Program and linkage"))[.](#argdep-4.sentence-2) If the lookup is for a dependent name ([[temp.dep]](temp.dep "13.8.3 Dependent names"), [[temp.dep.candidate]](temp.dep.candidate "13.8.4.2 Candidate functions")), the above lookup is also performed from each point in the instantiation context ([[module.context]](module.context "10.6 Instantiation 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.4 Global 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 void apply(T t, U u) { f(t, u); g(t);} Translation unit #3:module Q;import N;namespace S {struct Z { template 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.11 Identifiers [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.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]")[.](#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 struct B : A {};namespace N {template 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.2 Unqualified names")), if any, of - [(2.1)](#qual.general-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)](#qual.general-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"))[.](#qual.general-2.sentence-1) A [*qualified name*](#def:name,qualified "6.5.5.1 General [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.3 Qualified names [expr.prim.id.qual]"), * [(2.4.2)](#qual.general-2.4.2) a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]"), * [(2.4.3)](#qual.general-2.4.3) a [*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]"), * [(2.4.4)](#qual.general-2.4.4) a [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3 Namespace 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.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"))[.](#qual.general-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)[.](#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.3 Qualified 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.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[.](#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.2 Dependent 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.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[.](#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 using D = void; using T = void; void f();};using B = A;template using C = A;template using D = A;template using X = A; templatevoid g(T *p) { // as instantiated for g: 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.3 Qualified 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.3 Qualified 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.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[.](#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.1 Preamble")), 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.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The 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.1 General [dcl.decl.general]") of a (friend) declaration of a constructor or in a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The 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.3 Qualified names [expr.prim.id.qual]"), an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"), or a [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1 General [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.2 Namespace 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.4 Using 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.4 Using 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.1 Preamble [class.pre]") or enum keyword in an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") is followed by an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that is not followed by ​::​, lookup for the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is type-only ([[basic.lookup.general]](#general "6.5.1 General"))[.](#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.5 Elaborated type specifiers [dcl.type.elab]") depends on the following tokens[.](#elab-1.sentence-2) If the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is followed by ​::​, see [[basic.lookup.qual]](#qual "6.5.5 Qualified 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.5 Elaborated 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.3 Simple type specifiers [dcl.type.simple]"), the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated 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.5 Elaborated 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.5 Elaborated type specifiers"))struct Base::Data; // error: cannot introduce a qualified type ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated 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.4 Using namespace directive [namespace.udir]") or [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3 Namespace alias [namespace.alias]"), during the lookup for a [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") or for a name in a[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") only namespace names are considered[.](#udir-1.sentence-1)