Стандарт C++ 11 (1119564), страница 52
Текст из файла (страница 52)
If a friend function is called, its name may be found by the name lookup that considersfunctions from namespaces and classes associated with the types of the function arguments (3.4.2). If thename in a friend declaration is neither qualified nor a template-id and the declaration is a function oran elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shallnot consider any scopes outside the innermost enclosing namespace. [ Note: The other forms of frienddeclarations cannot declare a new member of the innermost enclosing namespace and thus follow the usuallookup rules.
— end note ] [ Example:// Assume f and g have not yet been defined.void h(int);template <class T> void f2(T);namespace A {class X {friend void f(X);// A::f(X) is a friendclass Y {friend void g();// A::g is a friendfriend void h(int);// A::h is a friend// ::h not consideredfriend void f2<>(int);// ::f2<>(int) is a friend};};// A::f, A::g and A::h are not visible hereX x;void g() { f(x); }// definition of A::gvoid f(X) { /* ... */}// definition of A::fvoid h(int) { /* ... */ }// definition of A::h// A::f, A::g and A::h are visible here and known to be friends}using A::x;void h() {A::f(x);A::X::f(x);A::X::Y::g();}// error: f is not a member of A::X// error: g is not a member of A::X::Y— end example ]7.3.21Namespace alias[namespace.alias]A namespace-alias-definition declares an alternate name for a namespace according to the following grammar:namespace-alias:identifiernamespace-alias-definition:namespace identifier = qualified-namespace-specifier ;qualified-namespace-specifier:nested-name-specifieropt namespace-name2The identifier in a namespace-alias-definition is a synonym for the name of the namespace denoted by thequalified-namespace-specifier and becomes a namespace-alias.
[ Note: When looking up a namespace-namein a namespace-alias-definition, only namespace names are considered, see 3.4.6. — end note ]§ 7.3.2164© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)3In a declarative region, a namespace-alias-definition can be used to redefine a namespace-alias declared inthat declarative region to refer only to the namespace to which it already refers. [ Example: the followingdeclarations are well-formed:namespacenamespacenamespacenamespaceCompany_with_very_long_name { /∗ ... ∗/ }CWVLN = Company_with_very_long_name;CWVLN = Company_with_very_long_name;CWVLN = CWVLN;// OK: duplicate— end example ]4A namespace-name or namespace-alias shall not be declared as the name of any other entity in the samedeclarative region.
A namespace-name defined at global scope shall not be declared as the name of anyother entity in any global scope of the program. No diagnostic is required for a violation of this rule bydeclarations in different translation units.7.3.31The using declaration[namespace.udecl]A using-declaration introduces a name into the declarative region in which the using-declaration appears.using-declaration:using typenameopt nested-name-specifier unqualified-id ;using :: unqualified-id ;The member name specified in a using-declaration is declared in the declarative region in which the usingdeclaration appears.
[ Note: Only the specified name is so declared; specifying an enumeration name in ausing-declaration does not declare its enumerators in the using-declaration’s declarative region. — end note ]If a using-declaration names a constructor (3.4.3.1), it implicitly declares a set of constructors in the class inwhich the using-declaration appears (12.9); otherwise the name specified in a using-declaration is a synonymfor the name of some entity declared elsewhere.2Every using-declaration is a declaration and a member-declaration and so can be used in a class definition.[ Example:struct B {void f(char);void g(char);enum E { e };union { int x; };};struct D : B {using B::f;void f(int) { f(’c’); }void g(int) { g(’c’); }};// calls B::f(char)// recursively calls D::g(int)— end example ]3In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of theclass being defined.
If such a using-declaration names a constructor, the nested-name-specifier shall name adirect base class of the class being defined; otherwise it introduces the set of declarations found by membername lookup (10.2, 3.4.3.1). [ Example:class C {int g();};§ 7.3.3© ISO/IEC 2011 – All rights reserved165ISO/IEC 14882:2011(E)class D2 : public B {using B::f;using B::e;using B::x;using C::g;};////////OK: B is a base of D2OK: e is an enumerator of base BOK: x is a union member of base Berror: C isn’t a base of D2— end example ]4[ Note: Since destructors do not have names, a using-declaration cannot refer to a destructor for a baseclass. Since specializations of member templates for conversion functions are not found by name lookup,they are not considered when a using-declaration specifies a conversion function (14.5.2).
— end note ] If anassignment operator brought from a base class into a derived class scope has the signature of a copy/moveassignment operator for the derived class (12.8), the using-declaration does not by itself suppress the implicitdeclaration of the derived class assignment operator; the copy/move assignment operator from the base classis hidden or overridden by the implicitly-declared copy/move assignment operator of the derived class, asdescribed below.5A using-declaration shall not name a template-id.
[ Example:struct A {template <class T> void f(T);template <class T> struct X { };};struct B : A {using A::f<double>;// ill-formedusing A::X<int>;// ill-formed};— end example ]6A using-declaration shall not name a namespace.7A using-declaration shall not name a scoped enumerator.8A using-declaration for a class member shall be a member-declaration.
[ Example:struct X {int i;static int s;};void f() {using X::i;using X::s;////////error: X::i is a class memberand this is not a member declaration.error: X::s is a class memberand this is not a member declaration.}— end example ]9Members declared by a using-declaration can be referred to by explicit qualification just like other membernames (3.4.3.2). In a using-declaration, a prefix :: refers to the global namespace. [ Example:void f();namespace A {void g();§ 7.3.3166© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)}namespace X {using ::f;using A::g;}void h(){X::f();X::g();}// global f// A’s g// calls ::f// calls A::g— end example ]10A using-declaration is a declaration and can therefore be used repeatedly where (and only where) multipledeclarations are allowed.
[ Example:namespace A {int i;}namespace A1 {using A::i;using A::i;}void f() {using A::i;using A::i;}// OK: double declaration// error: double declarationstruct B {int i;};struct X : B {using B::i;using B::i;};// error: double member declaration— end example ]11The entity declared by a using-declaration shall be known in the context using it according to its definitionat the point of the using-declaration. Definitions added to the namespace after the using-declaration are notconsidered when a use of the name is made. [ Example:namespace A {void f(int);}using A::f;// f is a synonym for A::f;// that is, for A::f(int).namespace A {void f(char);}§ 7.3.3© ISO/IEC 2011 – All rights reserved167ISO/IEC 14882:2011(E)void foo() {f(’a’);}void bar() {using A::f;f(’a’);// calls f(int),// even though f(char) exists.// f is a synonym for A::f;// that is, for A::f(int) and A::f(char).// calls f(char)}— end example ]12[ Note: Partial specializations of class templates are found by looking up the primary class template and thenconsidering all partial specializations of that template.
If a using-declaration names a class template, partialspecializations introduced after the using-declaration are effectively visible because the primary template isvisible (14.5.5). — end note ]13Since a using-declaration is a declaration, the restrictions on declarations of the same name in the samedeclarative region (3.3) also apply to using-declarations. [ Example:namespace A {int x;}namespace B {int i;struct g { };struct x { };void f(int);void f(double);void g(char);}void func() {int i;using B::i;void f(char);using B::f;f(3.5);using B::g;g(’a’);struct g g1;using B::x;using A::x;x = 99;struct x x1;}// OK: hides struct g// error: i declared twice// OK: each f is a function// calls B::f(double)// calls B::g(char)// g1 has class type B::g// OK: hides struct B::x// assigns to A::x// x1 has class type B::x— end example ]14If a function declaration in namespace scope or block scope has the same name and the same parametertypes as a function introduced by a using-declaration, and the declarations do not declare the same function,the program is ill-formed.