Every 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'); } };
— end example ]
[ Note: Since destructors do not have names, a using-declaration cannot refer to a destructor for a base class. 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 ([temp.mem]). — end note ] If an assignment operator brought from a base class into a derived class scope has the signature of a copy/move assignment operator for the derived class ([class.copy]), the using-declaration does not by itself suppress the implicit declaration of the derived class assignment operator; the copy/move assignment operator from the base class is hidden or overridden by the implicitly-declared copy/move assignment operator of the derived class, as described below.
A 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>; using A::X<int>; };
— end example ]
Members declared by a using-declaration can be referred to by explicit qualification just like other member names ([namespace.qual]). In a using-declaration, a prefix :: refers to the global namespace. [ Example:
void f(); namespace A { void g(); } namespace X { using ::f; using A::g; } void h(){ X::f(); X::g(); }
— end example ]
A using-declaration is a declaration and can therefore be used repeatedly where (and only where) multiple declarations are allowed. [ Example:
namespace A { int i; } namespace A1 { using A::i; using A::i; } void f() { using A::i; using A::i; } struct B { int i; }; struct X : B { using B::i; using B::i; };
— end example ]
Members added to the namespace after the using-declaration are not considered when a use of the name is made. [ Note: Thus, additional overloads added after the using-declaration are ignored, but default function arguments ([dcl.fct.default]), default template arguments ([temp.param]), and template specializations ([temp.class.spec], [temp.expl.spec]) are considered. — end note ] [ Example:
namespace A { void f(int); } using A::f; namespace A { void f(char); } void foo() { f('a'); } void bar() { using A::f; f('a'); }
— end example ]
[ Note: Partial specializations of class templates are found by looking up the primary class template and then considering all partial specializations of that template. If a using-declaration names a class template, partial specializations introduced after the using-declaration are effectively visible because the primary template is visible ([temp.class.spec]). — end note ]
Since a using-declaration is a declaration, the restrictions on declarations of the same name in the same declarative region ([basic.scope]) 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; }
— end example ]
If a function declaration in namespace scope or block scope has the same name and the same parameter-type-list ([dcl.fct]) as a function introduced by a using-declaration, and the declarations do not declare the same function, the program is ill-formed. If a function template declaration in namespace scope has the same name, parameter-type-list, return type, and template parameter list as a function template introduced by a using-declaration, the program is ill-formed. [ Note: Two using-declarations may introduce functions with the same name and the same parameter-type-list. If, for a call to an unqualified function name, function overload resolution selects the functions introduced by such using-declarations, the function call is ill-formed. [ Example:
namespace B { void f(int); void f(double); } namespace C { void f(int); void f(double); void f(char); } void h() { using B::f; using C::f; f('h'); f(1); void f(int); }
— end example ] — end note ]
When a using-declaration brings names from a base class into a derived class scope, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list ([dcl.fct]), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting). [ Note: For using-declarations that name a constructor, see [class.inhctor]. — end note ] [ Example:
struct B { virtual void f(int); virtual void f(char); void g(int); void h(int); }; struct D : B { using B::f; void f(int); using B::g; void g(char); using B::h; void h(int); }; void k(D* p){ p->f(1); p->f('a'); p->g(1); p->g('a'); }
— end example ]
For the purpose of overload resolution, the functions which are introduced by a using-declaration into a derived class will be treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function, and in all other respects the function remains a member of the base class.
The access rules for inheriting constructors are specified in [class.inhctor]; otherwise all instances of the name mentioned in a using-declaration shall be accessible. In particular, if a derived class uses a using-declaration to access a member of a base class, the member name shall be accessible. If the name is that of an overloaded member function, then all functions named shall be accessible. The base class members mentioned by a using-declaration shall be visible in the scope of at least one of the direct base classes of the class where the using-declaration is specified. [ Note: Because a using-declaration designates a base class member (and not a member subobject or a member function of a base class subobject), a using-declaration cannot be used to resolve inherited member ambiguities. For example,
struct A { int x(); }; struct B : A { }; struct C : A { using A::x; int x(int); }; struct D : B, C { using C::x; int x(double); }; int f(D* d) { return d->x(); }
— end note ]
The alias created by the using-declaration has the usual accessibility for a member-declaration. [ Note: A using-declaration that names a constructor does not create aliases; see [class.inhctor] for the pertinent accessibility rules. — end note ] [ Example:
class A { private: void f(char); public: void f(int); protected: void g(); }; class B : public A { using A::f; public: using A::g; };
— 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