using Directive

The using-directive allows the names in a namespace to be used without the namespace-name as an explicit qualifier. In contrast to a using declaration, which allows an individual name to be used without qualification, the using directive allows all the names in a namespace to be used without qualification. See using Declaration for more information.

Syntax

using-directive :

using namespace ::opt nested-name-specifieropt namespace-name

The intent of the using-directive is to allow unique, descriptive names to be used when declaring functions and variables, without requiring the complete name every time access to the functions or variables is needed. Of course, the complete, qualified name can still be used to retain clarity.

The unqualified names can be used from the point of the using directive on. If a namespace is extended after a using-directive is given, the additional members of the namespace can be used, without qualification, after the extended-namespace-definition. For example:

namespace M
{
    int i;
}

using namespace M;

namespace N
{
    int j;
    double f() { return M::d; }        // error: M::d does not yet exist
}

namespace M        // namespace extension
{
    double d;
}
                   // now M::d can be used

It is possible for a using-directive to introduce conflicting names when used in another namespace. For example:

namespace M
{
    int i;
}

namespace N
{
    int i;
    using namespace M;    // no error here
}
    .
    .
    .
void f()
{
    using namespace N;
    i = 7;                // error: ambiguous: M::i or N::i?
}

In this example, bringing M::i into namespace N does not hide the declaration of N::i, but instead creates an ambiguity when N::i is used. In this manner, the using-directive can easily introduce unintended ambiguities. Consider the following code fragment:

namespace D
{
    int d1;
    void f(int);
    void f(char);
}

using namespace D;

int d1;             // no conflict with D::d1

namespace E
{
    int e;
    void f(int);
}

namespace D         // namespace extension
{
    int d2;
    using namespace E;
    void f(int);
}

void f()
{
    d1++;           // error: ambiguous: ::d1 or D::d1?
    ::d1++;         // ok
    D::d1++;        // ok
    d2++;           // ok: D::d2
    e++;            // ok: E::e
    f(1);           // error: ambiguous: D::f(int) or E::f(int)?
    f('a');         // ok D::f(char)
}

When a variable is referenced after a using-directive, the local variable of the same name takes precedence over the one declared in the specified namespace. For example:

namespace N {
   int data = 4;
}

void f(bool flag) {
   int data = 0;

   if (flag) {
      using namespace N;
   
      prinf(“data=%d\n”, data);
   }
}

void main() {
   f(true);
}

In the above code, the variable data referenced in the printf statement is the local variable initialized to 0, instead of the variable initialized in namespace N. The output is data=0 instead of data=4.

In the presence of namespace using-directives, the way qualified names are looked up is shown in the following example:

namespace A {
   int flag = 0;
}

namespace B {
   using namespace A;
}

namespace C {
   using namespace A;
   using namespace B;
}

void main() {
   printf(“C::flag = %d\n”, C::flag);
}

The qualified name (C::flag) is resolved to (A::flag) due to the namespace using-directives in namespace C.