Стандарт C++ 11 (1119564), страница 19
Текст из файла (страница 19)
In addition, if the argument is the name or address of a set of overloaded functions and/or functiontemplates, its associated classes and namespaces are the union of those associated with each of the members ofthe set, i.e., the classes and namespaces associated with its parameter types and return type. Additionally,if the aforementioned set of overloaded functions is named with a template-id, its associated classes andnamespaces also include those of its type template-arguments and its template template-arguments.3Let X be the lookup set produced by unqualified lookup (3.4.1) and let Y be the lookup set produced byargument dependent lookup (defined as follows).
If X contains— a declaration of a class member, or— a block-scope function declaration that is not a using-declaration, or— a declaration that is neither a function or a function templatethen Y is empty. Otherwise Y is the set of declarations found in the namespaces associated with theargument types as described below. The set of declarations found by the lookup of the name is the union ofX and Y . [ Note: The namespaces and classes associated with the argument types can include namespacesand classes already considered by the ordinary unqualified lookup.
— end note ] [ Example: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);}// OK: calls NS::f// OK: calls g(NS::T, float)— end example ]4When considering an associated namespace, the lookup is the same as the lookup performed when theassociated namespace is used as a qualifier (3.4.3.2) except that:— Any using-directives in the associated namespace are ignored.§ 3.4.250© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)— Any namespace-scope friend functions or friend function templates declared in associated classes arevisible within their respective namespaces even if they are not visible during an ordinary lookup (11.3).— All names except those of (possibly overloaded) functions and function templates are ignored.3.4.31Qualified name lookup[basic.lookup.qual]The name of a class or namespace member or enumerator can be referred to after the :: scope resolutionoperator (5.1) 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 thename 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 programis ill-formed.[ Example:class A {public:static int n;};int main() {int A;A::n = 42;A b;}// OK// ill-formed: A does not name a type— end example ]2[ Note: Multiply qualified names, such as N1::N2::N3::n, can be used to refer to members of nestedclasses (9.7) or members of nested namespaces. — end note ]3In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declaredare looked up in the defining namespace scope; names following the qualified-id are looked up in the scopeof 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];// ill-formed:// equivalent to: ::X C::arr[C::number];// not to: C::X C::arr[C::number];— end example ]4A name prefixed by the unary scope operator :: (5.1) is looked up in global scope, in the translation unitwhere it is used. The name shall be declared in global namespace scope or shall be a name whose declarationis visible in global scope because of a using-directive (3.4.3.2). The use of :: allows a global name to bereferred to even if its identifier has been hidden (3.3.10).5A name prefixed by a nested-name-specifier that nominates an enumeration type shall represent an enumerator of that enumeration.6If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, the type-names are looked up as typesin the scope designated by the nested-name-specifier.
Similarly, in a qualified-id of the form:nested-name-specifieropt class-name ::~ class-name§ 3.4.3© ISO/IEC 2011 – All rights reserved51ISO/IEC 14882:2011(E)the second class-name is looked up in the same scope as the first. [ Example: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 Cq->I1::~I2();// I2 is looked up in the scope of// the postfix-expressionstruct A {~A();};typedef A AB;int main() {AB *p;p->AB::~AB();}// explicitly calls the destructor for A— end example ] [ Note: 3.4.5 describes how name lookup proceeds after the . and -> operators. — endnote ]3.4.3.11Class members[class.qual]If the nested-name-specifier of a qualified-id nominates a class, the name specified after the nested-namespecifier is looked up in the scope of the class (10.2), except for the cases listed below.
The name shallrepresent one or more members of that class or of one of its base classes (Clause 10). [ Note: A class membercan be referred to using a qualified-id at any point in its potential scope (3.3.7). — end note ] The exceptionsto the name lookup rule above are the following:— a destructor name is looked up as specified in 3.4.3;— a conversion-type-id of a conversion-function-id is looked up in the same manner as a conversion-type-idin a class member access (see 3.4.5);— the names in a template-argument of a template-id are looked up in the context in which the entirepostfix-expression occurs.— the lookup for a name specified in a using-declaration (7.3.3) also finds class or enumeration nameshidden within the same scope (3.3.10).2In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominatesa class C:— if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-nameof C (Clause 9), or— in a using-declaration (7.3.3) that is a member-declaration, if the name specified after the nested-namespecifier is the same as the identifier or the simple-template-id’s template-name in the last componentof the nested-name-specifier,the name is instead considered to name the constructor of class C.
[ Note: For example, the constructor isnot an acceptable lookup result in an elaborated-type-specifier so the constructor would not be used in placeof the injected-class-name. — end note ] Such a constructor name shall be used only in the declarator-id ofa declaration that names a constructor or in a using-declaration.
[ Example:§ 3.4.3.152© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)struct A { A(); };struct B: public A { B(); };A::A() { }B::B() { }B::A ba;A::A a;struct A::A a2;// object of type A// error, A::A is not a type name// object of type A— end example ]3A class member name hidden by a name in a nested declarative region or by the name of a derived classmember can still be found if qualified by the name of its class followed by the :: operator.3.4.3.2Namespace members[namespace.qual]1If the nested-name-specifier of a qualified-id nominates a namespace, the name specified after the nestedname-specifier is looked up in the scope of the namespace.
If a qualified-id starts with ::, the name after the:: is looked up in the global namespace. In either case, the names in a template-argument of a template-idare looked up in the context in which the entire postfix-expression occurs.2For a namespace X and name m, the namespace-qualified lookup set S(X, m) is defined as follows: LetS 0 (X, m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S 0 (X, m) is notempty, S(X, m) is S 0 (X, m); otherwise, S(X, m) is the union of S(Ni , m) for all namespaces Ni nominatedby using-directives in X and its inline namespace set.3Given X::m (where X is a user-declared namespace), or given ::m (where X is the global namespace), ifS(X, m) is the empty set, the program is ill-formed.
Otherwise, if S(X, m) has exactly one member, or ifthe context of the reference is a using-declaration (7.3.3), 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 programis 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;}§ 3.4.3.2© ISO/IEC 2011 – All rights reserved53ISO/IEC 14882:2011(E)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);//////////////////g is declared directly in AB,therefore S is { AB::g() } and AB::g() is chosenf is not declared directly in AB so the rules areapplied 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 overloadresolution chooses A::f(int)as above but resolution chooses B::f(char)//////////////////////////x is not declared directly in AB, andis not declared in A or B , so the rules areapplied recursively to Y and Z,S is { } so the program is ill-formedi is not declared directly in AB so the rules areapplied recursively to A and B,S is { A::i , B::i } so the use is ambiguousand the program is ill-formedh is not declared directly in AB andnot declared directly in A or B so the rules areapplied recursively to Y and Z,S is { Y::h(int), Z::h(double) } and overloadresolution chooses Z::h(double)}4The 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(){§ 3.4.3.254© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)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++;}5// OK: S is {A::a, A::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++;}////////OK:OK:OK:OK:a declared directly in A, S is { A::a}both A and B searched (once), S is { A::a}both A and B searched (once), S is { B::b}b declared directly in B, S is { B::b}— end example ]6During the lookup of a qualified namespace member name, if the lookup finds more than one declaration ofthe member, and if one declaration introduces a class name or enumeration name and the other declarationseither introduce the same variable, the same enumerator or a set of functions, the non-type name hidesthe class or enumeration name if and only if the declarations are from the same namespace; otherwise (thedeclarations are from different namespaces), the program is ill-formed.
[ Example:namespace A {struct x { };int x;int y;}namespace B {struct y { };§ 3.4.3.2© ISO/IEC 2011 – All rights reserved55ISO/IEC 14882:2011(E)}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 ]7In a declaration for a namespace member in which the declarator-id is a qualified-id, given that the qualified-idfor the namespace member has the formnested-name-specifier unqualified-idthe unqualified-id shall name a member of the namespace designated by the nested-name-specifier or of anelement of the inline namespace set (7.3.1) of that namespace.