Стандарт C++ 98 (1119566), страница 12
Текст из файла (страница 12)
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 (3.4.3.2). The use of :: allows a global name tobe referred to even if its identifier has been hidden (3.3.7).5If a pseudo-destructor-name (5.2.4) contains a nested-name-specifier, the type-names are looked up astypes in the scope designated by the nested-name-specifier.
In a qualified-id of the form:::opt nested-name-specifier ~ class-namewhere the nested-name-specifier designates a namespace scope, and in a qualified-id of the form:::opt nested-name-specifier class-name :: ~ class-namethe class-names are looked up as types in the scope designated by the nested-name-specifier. [Example:struct C {typedef int I;};typedef int I1, I2;extern int* p;extern int* q;p->C::I::~I();q->I1::~I2();34// I is looked up in the scope of C// I2 is looked up in the scope of// the postfix-expression© ISO/IECISO/IEC 14882:1998(E)3 Basic conceptsstruct A {~A();};typedef A AB;int main(){AB *p;p->AB::~AB();}3.4.3 Qualified name lookup// explicitly calls the destructor for A—end example] [Note: 3.4.5 describes how name lookup proceeds after the .
and -> operators. ]3.4.3.1 Class members1[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 shall represent 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.6).
] The exceptions to thename lookup rule above are the following:— a destructor name is looked up as specified in 3.4.3;— a conversion-type-id of an operator-function-id is looked up both in the scope of the class and in thecontext in which the entire postfix-expression occurs and shall refer to the same type in both contexts;— the template-arguments of a template-id are looked up in the context in which the entire postfixexpression occurs.2A 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.2 Namespace 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, except that the template-arguments of atemplate-id are looked up in the context in which the entire postfix-expression occurs.2Given X::m (where X is a user-declared namespace), or given ::m (where X is the global namespace), letS be the set of all declarations of m in X and in the transitive closure of all namespaces nominated byusing-directives in X and its used namespaces, except that using-directives are ignored in any namespace,including X, directly containing one or more declarations of m.
No namespace is searched more than oncein the lookup of a name. If S is the empty set, the program is ill-formed. Otherwise, if S has exactly onemember, or if the context of the reference is a using-declaration (7.3.3), S is the required set of declarationsof m. Otherwise if the use of m is not one that allows a unique declaration to be chosen from S, the programis ill-formed.
[Example:int x;namespace Y {void f(float);void h(int);}namespace Z {void h(double);}35ISO/IEC 14882:1998(E)3.4.3.2 Namespace members© ISO/IEC3 Basic conceptsnamespace 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);// g is declared directly in AB,// therefore S is { AB::g() } and AB::g() is chosen// 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)// as above but resolution chooses B::f(char)// 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// 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// 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)}3The 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;}36© ISO/IECISO/IEC 14882:1998(E)3 Basic concepts3.4.3.2 Namespace membersnamespace 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++;}4// 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: a declared directly in A, S is { A::a }// OK: both A and B searched (once), S is { A::a }// OK: both A and B searched (once), S is { B::b }// OK: b declared directly in B, S is { B::b }—end example]5During 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 object, the same enumerator or a set of functions, the non-type name hides theclass 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;}37ISO/IEC 14882:1998(E)© ISO/IEC3.4.3.2 Namespace members3 Basic conceptsnamespace B {struct y {};}namespace C {usingusingint iint j}namespace A;namespace B;= C::x;= C::y;// OK, A::x (of type int)// ambiguous, A::y or B::y—end example]6In a declaration for a namespace member in which the declarator-id is a qualified-id, given that thequalified-id for 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. [Example:namespace A {namespace B {void f1(int);}using namespace B;}void A::f1(int) { }// ill-formed, f1 is not a member of A—end example] However, in such namespace member declarations, the nested-name-specifier may rely onusing-directives to implicitly provide the initial part of the nested-name-specifier.
[Example: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]3.4.4 Elaborated type specifiers[basic.lookup.elab]1An elaborated-type-specifier may be used to refer to a previously declared class-name or enum-name eventhough the name has been hidden by a non-type declaration (3.3.7). The class-name or enum-name in theelaborated-type-specifier may either be a simple identifer or be a qualified-id.2If the name in the elaborated-type-specifier is a simple identifer, and unless the elaborated-type-specifierhas the following form:class-key identifier ;the identifier is looked up according to 3.4.1 but ignoring any non-type names that have been declared. Ifthis name lookup finds a typedef-name, the elaborated-type-specifier is ill-formed.
If the elaborated-typespecifier refers to an enum-name and this lookup does not find a previously declared enum-name, the38© ISO/IECISO/IEC 14882:1998(E)3 Basic concepts3.4.4 Elaborated type specifierselaborated-type-specifier is ill-formed. If the elaborated-type-specifier refers to an class-name and thislookup does not find a previously declared class-name, or if the elaborated-type-specifier has the form:class-key identifier ;the elaborated-type-specifier is a declaration that introduces the class-name as described in 3.3.1.3If the name is a qualified-id, the name is looked up according its qualifications, as described in 3.4.3, butignoring any non-type names that have been declared.