[basic.lookup] (original) (raw)
6 Basics [basic]
6.5 Name lookup [basic.lookup]
6.5.1 General [basic.lookup.general]
Name lookup associates the use of a name with a set of declarations ([basic.def]) of that name.
Unless otherwise specified, the program is ill-formed if no declarations are found.
If the declarations found by name lookup all denote functions or function templates, the declarations are said to form an overload set.
Otherwise, if the declarations found by name lookup do not all denote the same entity,they are ambiguous and the program is ill-formed.
The access rules ([class.access]) are considered only once name lookup and function overload resolution (if applicable) have succeeded.
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.
A program point P is said to follow any declaration in the same translation unit whose locus ([basic.scope.pdecl]) is before P.
[Note 1:
The declaration might appear in a scope that does not contain P.
— _end note_]
A declaration X precedesa program point P in a translation unit Lif P follows X, X inhabits a class scope and is reachable from P, or else X appears in a translation unit D and
- P follows a module-import-declaration or module-declarationthat imports D (directly or indirectly), and
- X appears after the module-declaration in D (if any) and before the private-module-fragment in D (if any), and
- 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.
[Note 3:
[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); } — _end example_]
— _end note_]
A single search in a scope Sfor a name N from a program point Pfinds all declarations that precede Pto which any name that is the same as N ([basic.pre]) is bound in S.
In certain contexts, only certain kinds of declarations are included.
After any such restriction, any declarations of classes or enumerations are discarded if any other declarations are found.
[Note 4:
A type (but not a typedef-name or template) is therefore hidden by any other entity in its scope.
— _end note_]
However, if a lookup is type-only, only declarations of types and templates whose specializations are types are considered; furthermore, if declarations of a typedef-name and of the type to which it refers are found, the declaration of the typedef-name is discarded instead of the type declaration.
6.5.2 Member name lookup [class.member.lookup]
A search in a scope X for a name M from a program point Pis a single search in X for M from Punless X is the scope of a class or class template T, in which case the following steps define the result of the search.
[Note 1:
The result differs only if M is a conversion-function-id or if the single search would find nothing.
— _end note_]
The lookup set for a name N in a class or class template C, called S(N,C), consists of two component sets: the declaration set, a set of members named N; and the subobject set, a set of subobjects where declarations of these members were found (possibly via using-declarations).
In the declaration set, type declarations (including injected-class-names) are replaced by the types they designate.
S(N,C) is calculated as follows:
The declaration set is the result of a single search in the scope of C for Nfrom immediately after the class-specifier of Cif P is in a complete-class context of C or from P otherwise.
If the resulting declaration set is not empty, the subobject set contains C itself, and calculation is complete.
Otherwise (i.e., C does not contain a declaration of Nor the resulting declaration set is empty), S(N,C) is initially empty.
Calculate the lookup set for Nin each direct non-dependent ([temp.dep.type]) base class subobject , and merge each such lookup set in turn into S(N,C).
[Note 2:
If C is incomplete, only base classes whose base-specifier appears before Pare considered.
If C is an instantiated class, its base classes are not dependent.
— _end note_]
The following steps define the result of merging lookup set into the intermediate S(N,C):
- If each of the subobject members of is a base class subobject of at least one of the subobject members of S(N,C), or if is empty, S(N,C) is unchanged and the merge is complete.
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 , or ifS(N,C) is empty, the new S(N,C) is a copy of . - Otherwise, if the declaration sets of 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.
In subsequent merges, an invalid declaration set is considered different from any other. - Otherwise, the new S(N,C) is a lookup set with the shared set of declarations and the union of the subobject sets.
The result of the search is the declaration set of S(M,T).
If it is an invalid set, the program is ill-formed.
If it differs from the result of a search in T for Min a complete-class context ([class.mem]) of T, the program is ill-formed, no diagnostic required.
[Example 1: struct A { int x; }; struct B { float x; }; struct C: public A, public B { }; struct D: public virtual C { }; struct E: public virtual C { char x; }; struct F: public D, public E { }; int main() { F f; f.x = 0; }
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.
— _end example_]
If M is a non-dependent conversion-function-id, conversion function templates that are members of T are considered.
For each such template F, the lookup set S(t,T) is constructed, considering a function template declaration to have the name tonly if it corresponds to a declaration of F ([basic.scope.scope]).
The members of the declaration set of each such lookup set, which shall not be an invalid set, are included in the result.
[Note 3:
Overload resolution will discard those that cannot convert to the type specified by M ([temp.over]).
— _end note_]
[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.
Two base class subobjects share the non-static member subobjects of their common virtual base classes.
— _end note_]
[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++; pd->s++; int i = pd->e; pd->a++; } — _end example_]
[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.
This is not an ambiguity.
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.
— _end note_]
[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(); };
virt W1 W V V W2 W B B B->W1 B->V C C C->V C->W2 D D D->B D->C
Figure 1 — Name lookup [fig:class.lookup]
As illustrated in Figure 1, the names declared in V and the left-hand instance of Ware hidden by those in B, but the names declared in the right-hand instance of W are not hidden at all.
void D::glorp() { x++; f(); y++; g(); } — _end example_]
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.
[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; V* pv = &d; } — _end example_]
[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(); f(0); f(0.0); int B1::* mpB1 = &D::i; int D::* mpD = &D::i; } }; — _end example_]
6.5.3 Unqualified name lookup [basic.lookup.unqual]
A using-directive isactive in a scope S at a program point Pif it precedes P and inhabits either S or the scope of a namespace nominated by a using-directivethat is active in S at P.
An unqualified search in a scope S from a program point Pincludes the results of searches from P in
- S, and
- 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 that is active in U at P.
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.
[Note 1:
When a class scope is searched, the scopes of its base classes are also searched ([class.member.lookup]).
If it inherits from a single base, it is as if the scope of the base immediately contains the scope of the derived class.
Template parameter scopes that are associated with one scope in the chain of parents are also considered ([temp.local]).
— _end note_]
Unqualified name lookupfrom a program point performs an unqualified search in its immediate scope.
An unqualified name is a name that does not immediately follow a nested-name-specifier or the . or -> in a class member access expression ([expr.ref]), possibly after a template keyword or ~.
Unless otherwise specified, such a name undergoes unqualified name lookup from the point where it appears.
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.
[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::*(); X().operator U decltype(T())::*(); return 0;} int x = g<B, T2>(); — _end example_]
In a friend declaration declaratorwhose declarator-id is a qualified-idwhose lookup context ([basic.lookup.qual]) is a class or namespace S, lookup for an unqualified name that appears after the declarator-idperforms a search in the scope associated with S.
If that lookup finds nothing, it undergoes unqualified name lookup.
[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); friend void A::f(D); friend void A::f(C); friend void A::f(F); friend void W::X::g(I); friend void W::X::g(D); friend void W::X::g(F); };} — _end example_]
6.5.4 Argument-dependent name lookup [basic.lookup.argdep]
When the postfix-expression in a function call ([expr.call]) is an unqualified-id, and unqualified lookup ([basic.lookup.unqual]) for the name in the unqualified-id does not find any
- declaration of a class member, or
- function declaration inhabiting a block scope, or
- declaration not of a function or function template
then lookup for the name also includes the result ofargument-dependent lookup 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.
[Example 1: namespace N { struct S { };void f(S);} void g() { N::S s; f(s); (f)(s); } — _end example_]
[Note 1:
For purposes of determining (during parsing) whether an expression is apostfix-expression for a function call, the usual name lookup rules apply.
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()); int y = g<N::A>(N::A()); int z = h<N::A>(N::A());
The rules have no effect on the syntactic interpretation of an expression.
For example,typedef int f;namespace N { struct A { friend void f(A &);operator int();void g(A a) { int i = f(a); } };}
Because the expression is not a function call, argument-dependent name lookup does not apply and the friend function f is not found.
— _end note_]
For each argument type T in the function call, there is a set of zero or more associated entitiesto be considered.
The set of entities is determined entirely by the types of the function arguments (and any type template template arguments).
The set of entities is determined in the following way:
- If T is a fundamental type, its associated set of entities is empty.
- 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.
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.
[Note 2:
Constant template arguments, variable template template arguments, and concept template arguments do not contribute to the set of associated entities.
— _end note_] - If T is an enumeration type, its associated entities are Tand, if it is a class member, the member's class.
- If T is a pointer to U or an array of U, its associated entities are those associated with U.
- If T is a function type, its associated entities are those associated with the function parameter types and those associated with the return type.
- 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.
- 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.
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.
Additionally, if the aforementioned overload set is named with a template-id, its associated entities also include its template template arguments and those associated with its type template arguments.
The 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]) of those namespaces.
Argument-dependent lookup finds all declarations of functions and function templates that
- are found by a search of any associated namespace, or
- are declared as a friend ([class.friend]) of any class with a reachable definition in the set of associated entities, or
- are exported, are attached to a named module M ([module.interface]), 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]).
If the lookup is for a dependent name ([temp.dep], [temp.dep.candidate]), the above lookup is also performed from each point in the instantiation context ([module.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]) or has internal linkage.
[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(); R::f(x); f(x); f(x, S::Z()); apply(x, S::Z()); } — _end example_]
[Note 3:
The associated namespace can include namespaces already considered by ordinary unqualified lookup.
— _end note_]
[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); extern void g(NS::T, float); g(parm, 1); } — _end example_]
6.5.5 Qualified name lookup [basic.lookup.qual]
6.5.5.1 General [basic.lookup.qual.general]
Lookup of an identifierfollowed by a :: scope resolution operator considers only namespaces, types, and templates whose specializations are types.
[Example 1: class A { public: static int n;};int main() { int A; A::n = 42; A b; } template<int> struct B : A {};namespace N { template<int> void B();int f() { return B<0>::n; } } — _end example_]
A qualified name is
- a member-qualified name or
- the terminal name of
The lookup context of a member-qualified name is the type of its associated object expression (considered dependent if the object expression is type-dependent).
The lookup context of any other qualified name is the type, template, or namespace nominated by the preceding nested-name-specifier.
[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.
— _end note_]
[Example 2:
In N::C::m.Base::f() Base is a member-qualified name; the other qualified names are C, m, and f.
— _end example_]
Qualified name lookupin a class, namespace, or enumeration performs a search of the scope associated with it ([class.member.lookup]) except as specified below.
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]) or is not a class or class template.
If nothing is found by qualified lookup for a member-qualified name that is the terminal name ([expr.prim.id.unqual]) of a nested-name-specifier and is not dependent, it undergoes unqualified lookup.
[Note 2:
During lookup for a template specialization, no names are dependent.
— _end note_]
[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) { p->X<0>::f(); p->template X<0>::f(); p->B::f(); p->template C<0>::f(); p->template D<0>::f(); p->T::f(); } template void g(A*); — _end example_]
If a qualified name Q follows a ~:
- If Q is a member-qualified name, it undergoes unqualified lookup as well as qualified lookup.
- If N has another nested-name-specifier S,Q is looked up as if its lookup context were that nominated by S.
- 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).
- Otherwise, Q undergoes unqualified lookup.
- Each lookup for Q considers only types (if Q is not followed by a <) and templates whose specializations are types.
If it finds nothing or is ambiguous, it is discarded. - The type-name that is or contains Qshall refer to its (original) lookup context (ignoring cv-qualification) under the interpretation established by at least one (successful) lookup performed.
[Example 4: struct C { typedef int I;};typedef int I1, I2;extern int* p;extern int* q;void f() { p->C::I::~I(); q->I1::~I2(); } struct A { ~A();};typedef A AB;int main() { AB* p; p->AB::~AB(); } — _end example_]
6.5.5.2 Class members [class.qual]
In a lookup for a qualified name N whose lookup context is a class Cin which function names are not ignored,18
- if the search finds the injected-class-name of C ([class.pre]), or
- if N is dependent and is the terminal name of a using-declarator ([namespace.udecl]) that names a constructor,
N is instead considered to name the constructor of class C.
Such a constructor name shall be used only in the declarator-id of a (friend) declaration of a constructor or in a using-declaration.
[Example 1: struct A { A(); };struct B: public A { B(); }; A::A() { }B::B() { }B::A ba; A::A a; struct A::A a2; — _end example_]
6.5.5.3 Namespace members [namespace.qual]
Qualified name lookup in a namespace N additionally searches every element of the inline namespace set of N ([namespace.def]).
If nothing is found, the results of the lookup are the results of qualified name lookup in each namespace nominated by a using-directivethat precedes the point of the lookup and inhabits N or an element of N's inline namespace set.
[Note 1:
If a using-directive refers to a namespace that has already been considered, it does not affect the result.
— _end note_]
[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(); AB::f(1); AB::f('c'); AB::x++; AB::i++; AB::h(16.8); } — _end example_]
[Note 2:
The same declaration found more than once is not an ambiguity (because it is still a unique declaration).
[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++; } namespace D { using A::a;} namespace BD { using namespace B;using namespace D;} void g() { BD::a++; } — _end example_]
— _end note_]
[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++; B::a++; A::b++; B::b++; }
— _end example_]
[Note 3:
Class and enumeration declarations are not discarded because of other declarations found in other searches.
— _end note_]
[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; int j = C::y; } — _end example_]
6.5.6 Elaborated type specifiers [basic.lookup.elab]
[Example 1: struct Node { struct Node* Next; struct Data* Data; };struct Data { struct Node* Node; friend struct ::Glob; friend struct Glob; };struct Base { struct Data; struct ::Data* thatData; struct Base::Data* thisData; friend class ::Data; friend class Data; struct Data { }; };struct Data; struct ::Data; struct Base::Data; struct Base::Datum; struct Base::Data* pBase; — _end example_]