using [typename][::] nested-name-specifier unqualified-id using :: unqualified-id
The using declaration introduces a name into the declarative region in which the using declaration appears. The name becomes a synonym for an entity declared elsewhere. It allows an individual name from a specific namespace to be used without explicit qualification. This is in contrast to the using directive, which allows allthe names in a namespace to be used without qualification. See using Directive for more information.
A using-declaration can be used in a class definition. For example:
class B { void f(char); void g(char); }; class D : B { using B::f; void f(int) { f('c'); } // calls B::f(char) void g(int) { g('c'); } // recursively calls D::g(int) // only B::f is being used };
When used to declare a member, a using-declaration must refer to a member of a base class. For example:
class C { int g(); }; class D2 : public B { using B::f; // ok: B is a base of D2 using C::g; // error: C isn't a base of D2 };
Members declared with a using-declaration can be referenced using explicit qualification. The :: prefix refers to the global namespace. For example:
void f(); namespace A { void g(); } namespace X { using ::f; // global f using A::g; // A's g } void h() { X::f(); // calls ::f X::g(); // calls A::g }
Just as with any declaration, a using-declaration can be used repeatedly only where multiple declarations are allowed. For example:
namespace A { int i; } void f() { using A::i; using A::i; // ok: double declaration } class B { protected: int i; }; class X : public B { public: using B::i; using B::i; // error: class members cannot be multiply declared };
When a using-declaration is made, the synonym created by the declaration refers only to definitions that are valid at the point of the using-declaration. Definitions added to a namespace after the using-declaration are not valid synonyms. For example:
namespace A { void f(int); } using A::f; // f is a synonym for A::f(int) only namespace A { void f(char); } void f() { f('a'); // refers to A::f(int), even though A::f(char) exists } void b() { using A::f; // refers to A::f(int) AND A::f(char) f('a'); // calls A::f(char); }
A name defined by a using-declaration is an alias for its original name. It does not affect the type, linkage or other attributes of the original declaration.
If a set of local declarations and using-declarations for a single name are given in a declarative region, they must all refer to the same entity, or they must all refer to functions. For example:
namespace B { int i; void f(int); void f(double); } void g() { int i; using B::i; // error: i declared twice void f(char); using B::f; // ok: each f is a function }
In the example above, the using B::i
statement causes a second int i
to be declared in the g()
function. The using B::f
statement does not conflict with the f(char)
function because the function names introduced by B::f
have different parameter types.
A local function declaration cannot have the same name and type as a function introduced by a using-declaration. For 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; // introduces B::f(int) and B::f(double) using C::f; // C::f(int), C::f(double), and C::f(char) f('h'); // calls C::f(char) f(1); // error: ambiguous: B::f(int) or C::f(int)? void f(int); // error: conflicts with B::f(int) and C::f(int) }
When a using-declaration introduces a name from a base class into a derived class scope, member functions in the derived class override virtual member functions with the same name and argument types in the base class. For 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); // ok: D::f(int) overrides B::f(int) using B::g; void g(char); // ok: there is no B::g(char) using B::h; void h(int); // error: D::h(int) conflicts with B::h(int) // B::h(int) is not virtual }; void f(D* pd) { pd->f(1); // calls D::f(int) pd->f('a'); // calls B::f(char) pd->g(1); // calls B::g(int) pd->g('a'); // calls D::g(char) }
All instances of a name mentioned in a using-declaration must be accessible. In particular, if a derived class uses a using-declaration to access a member of a base class, the member name must be accessible. If the name is that of an overloaded member function, then all functions named must be accessible. For example:
class A { private: void f(char); public: void f(int); protected: void g(); }; class B : public A { using A::f; // error: A::f(char) is inaccessible public: using A::g; // B::g is a public synonym for A::g }; from: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/tions_43.asp