6 Basics [basic]

6.5 Name lookup [basic.lookup]

6.5.4 Qualified name lookup [basic.lookup.qual]

6.5.4.1 General [basic.lookup.qual.general]

The name of a class or namespace member or enumerator can be referred to after the ​::​ scope resolution operator ([expr.prim.id.qual]) applied to a nested-name-specifier that denotes its class, namespace, or enumeration.
If a ​::​ scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that ​::​ considers only namespaces, types, and templates whose specializations are types.
If the name found does not designate a namespace or a class, enumeration, or dependent type, the program is ill-formed.
[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 } — end example]
[Note 1:
Multiply qualified names, such as N1​::​N2​::​N3​::​n, can be used to refer to members of nested classes ([class.nest]) or members of nested namespaces.
— end note]
In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declared are looked up in the defining namespace scope; names following the qualified-id are looked up in the scope of the member's class or namespace.
[Example 2: class X { }; class C { class X { }; static const int number = 50; static X arr[number]; }; X C::arr[number]; // error: // equivalent to ​::​X C​::​arr[C​::​number]; // and not to C​::​X C​::​arr[C​::​number]; — end example]
A name prefixed by the unary scope operator ​::​ ([expr.prim.id.qual]) is looked up in global scope, in the translation unit where it is used.
The name shall be declared in global namespace scope or shall be a name whose declaration is visible in global scope because of a using-directive ([namespace.qual]).
The use of ​::​ allows a global name to be referred to even if its identifier has been hidden.
A name prefixed by a nested-name-specifier that nominates an enumeration type shall represent an enumerator of that enumeration.
In a qualified-id of the form: the second type-name is looked up in the same scope as the first.
[Example 3: struct C { typedef int I; }; typedef int I1, I2; extern int* p; extern int* q; p->C::I::~I(); // I is looked up in the scope of C q->I1::~I2(); // I2 is looked up in the scope of the postfix-expression struct A { ~A(); }; typedef A AB; int main() { AB* p; p->AB::~AB(); // explicitly calls the destructor for A } — end example]
[Note 2:
[basic.lookup.classref] describes how name lookup proceeds after the . and -> operators.
— end note]

6.5.4.2 Class members [class.qual]

If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-name-specifier is looked up in the scope of the class ([class.member.lookup]), except for the cases listed below.
The name shall represent one or more members of that class or of one of its base classes ([class.derived]).
[Note 1:
A class member can be referred to using a qualified-id at any point in its potential scope ([basic.scope.class]).
— end note]
The exceptions to the name lookup rule above are the following:
In a lookup in which function names are not ignored28 and the nested-name-specifier nominates a class C: the name is instead considered to name the constructor of class C.
[Note 2:
For example, the constructor is not an acceptable lookup result in an elaborated-type-specifier so the constructor would not be used in place of the injected-class-name.
— end note]
Such a constructor name shall be used only in the declarator-id of a declaration that names a constructor or in a using-declaration.
[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 name struct A::A a2; // object of type A — end example]
A class member name hidden by a name in a nested declarative region or by the name of a derived class member can still be found if qualified by the name of its class followed by the ​::​ operator.
Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.
 

6.5.4.3 Namespace members [namespace.qual]

If the nested-name-specifier of a qualified-id nominates a namespace (including the case where the nested-name-specifier is ​::​, i.e., nominating the global namespace), the name specified after the nested-name-specifier is looked up in the scope of the namespace.
The names in a template-argument of a template-id are looked up in the context in which the entire postfix-expression occurs.
For a namespace X and name m, the namespace-qualified lookup set is defined as follows: Let be the set of all declarations of m in X and the inline namespace set of X ([namespace.def]) whose potential scope ([basic.scope.namespace]) would include the namespace in which m is declared at the location of the nested-name-specifier.
If is not empty, is ; otherwise, is the union of for all namespaces nominated by using-directives in X and its inline namespace set.
Given X​::​m (where X is a user-declared namespace), or given ​::​m (where X is the global namespace), if is the empty set, the program is ill-formed.
Otherwise, if has exactly one member, or if the context of the reference is a using-declaration ([namespace.udecl]), is the required set of declarations of m.
Otherwise if the use of m is not one that allows a unique declaration to be chosen from , the program is ill-formed.
[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 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 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 and // overload resolution chooses Z​::​h(double) } — end example]
[Note 1:
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++; // OK: S is } namespace D { using A::a; } namespace BD { using namespace B; using namespace D; } void g() { BD::a++; // OK: S is } — 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++; // 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]
During the lookup of a qualified namespace member name, if the lookup finds more than one declaration of the member, and if one declaration introduces a class name or enumeration name and the other declarations introduce either the same variable, the same enumerator, or a set of functions, the non-type name hides the class or enumeration name if and only if the declarations are from the same namespace; otherwise (the declarations are from different namespaces), the program is ill-formed.
[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]
In a declaration for a namespace member in which the declarator-id is a qualified-id, given that the qualified-id for the namespace member has the form the unqualified-id shall name a member of the namespace designated by the nested-name-specifier or of an element of the inline namespace set of that namespace.
[Example 5: namespace A { namespace B { void f1(int); } using namespace B; } void A::f1(int){ } // error: f1 is not a member of A — end example]
However, in such namespace member declarations, the nested-name-specifier may rely on using-directives to implicitly provide the initial part of the nested-name-specifier.
[Example 6: namespace A { namespace B { void f1(int); } } namespace C { namespace D { void f1(int); } } using namespace A; using namespace C::D; void B::f1(int){ } // OK, defines A​::​B​::​f1(int) — end example]