The name of a class or namespace member or enumerator can be referred to after the :: scope resolution operator ([expr.prim]) 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:
class A { public: static int n; }; int main() { int A; A::n = 42; A b; }
— end example ]
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:
class X { }; class C { class X { }; static const int number = 50; static X arr[number]; }; X C::arr[number];
— end example ]
3.4.3.1 Class members [class.qual]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.
3.4.3.2 Namespace members [namespace.qual]For a namespace X and name m, the namespace-qualified lookup set S(X, m) is defined as follows: Let S'(X, m) be the set of all declarations of m in X and the inline namespace set of X ([namespace.def]). If S'(X, m) is not empty, S(X, m) is S'(X, m); otherwise, S(X, m) is the union of S(Ni, m) for all namespaces Ni 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 S(X, m) is the empty set, the program is ill-formed. Otherwise, if S(X, m) has exactly one member, or if the context of the reference is a using-declaration ([namespace.udecl]), S(X, m) 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 S(X, m), the program is ill-formed. [ Example:
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); }
The same declaration found more than once is not an ambiguity (because it is still a unique declaration). For example:
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++; }
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 ]
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 either introduce 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:
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 ]
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4