Export (0) Print
Expand All
3 out of 4 rated this helpful - Rate this topic

using Declaration

The using declaration introduces a name into the declarative region in which the using declaration appears.

Grammar

using-declaration:
using [typename][::] nested-name-specifier unqualified-id
using :: unqualified-id

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 all the 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:

// using_declaration1.cpp
#include <stdio.h>
class B
{
public:
   void f(char)
   {
      printf("In B::f()\n");
   }

   void g(char)
   {
      printf("In B::g()\n");
   }
};

class D : B
{
public:
   using B::f;
   using B::g;
   void f(int)
   {
      printf("In D::f()\n");
      f('c');
   }

   void g(int)
   {
      printf("In D::g()\n");
      g('c');
   }
};

int main()
{
   D myD;
   myD.f(1);
   myD.g('a');
}

Output

In D::f()
In B::f()
In B::g()

When used to declare a member, a using-declaration must refer to a member of a base class. For example:

// using_declaration2.cpp
#include <stdio.h>

class B
{
public:
   void f(char)
   {
      printf("In B::f()\n");
   }

   void g(char)
   {
      printf("In B::g()\n");
   }
};


class C
{
public:
   int g();
};

class D2 : public B
{
public:
   using B::f;   // ok: B is a base of D2
   // using C::g;   // error: C isn't a base of D2
};


int main()
{
   D2 MyD2;
   MyD2.f('a');
}

Output

In B::f()

Members declared with a using-declaration can be referenced using explicit qualification. The :: prefix refers to the global namespace. For example:

// using_declaration3.cpp
#include <stdio.h>

void f()
{
   printf("In f\n");
}

namespace A
{
   void g()
   {
      printf("In A::g\n");
   }
}

namespace X
{
   using ::f;   // global f
   using A::g;   // A's g
}

void h()
{
   printf("In h\n");
   X::f();   // calls ::f
   X::g();   // calls A::g
}

int main()
{
   h();
}

Output

In h
In f
In A::g

Post-declaration Namespace Additions

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:

// post_declaration_namespace_additions.cpp
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);
}

int main()
{
}

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.

Functions in Namespaces

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:

// functions_in_namespaces1.cpp
// C2874 expected
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:

// functions_in_namespaces2.cpp
// C2668 expected
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);                // C2668: ambiguous: B::f(int) or C::f(int)?
    void f(int);         // C2883: conflicts with B::f(int) and C::f(int)
}

Inheritance

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:

// using_declaration_inheritance1.cpp
#include <stdio.h>
struct B
{
   virtual void f(int)
   {
      printf("In D::f(int)\n");
   }
   virtual void f(char)
   {
      printf("In D::f(char)\n");
   }
   void g(int)
   {
      printf("In B::g\n");
   }

   void h(int);
};

struct D : B
{
   using B::f;
   void f(int)   // ok: D::f(int) overrides B::f(int)
   {
      printf("In D::f\n");
   }

   using B::g;
   void g(char)   // ok: there is no B::g(char)
   {
      printf("In D::g\n");
   }

   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)
}

int main()
{
   D * myd = new D();
   f(myd);
}

Output

In D::f
In D::f(char)
In B::g
In D::g

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:

// using_declaration_inheritance2.cpp
// C2876 expected
class A
{
private:
   void f(char);
public:
   void f(int);
protected:
   void g();
};

class B : public A
{
   using A::f;   // C2876: A::f(char) is inaccessible
public:
   using A::g;   // B::g is a public synonym for A::g
};

See Member-Access Control, for more information on accessibility of members.

See Also

Namespaces | C++ Keywords

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.