Maestro
Maestro

Reputation: 2552

How and where using directive injects member names?

AFAIK a using directive exposes or injects all the names of a namespace in the nearest enclosing namespace. and here is from C++ primer:

In contrast, a using directive makes the entire contents of a namespace available In general, a namespace might include definitions that cannot appear in a local scope. As a consequence, a using directive is treated as if it appeared in the nearest enclosing namespace scope.

In the simplest case, assume we have a namespace A and a function f, both defined at global scope. If f has a using directive for A, then in f it will be as if the names in A appeared in the global scope prior to the definition of f

And from cppreference:

  1. using-directive: From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from ns_name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and ns_name.
#include <iostream>

int x = 1;
int y = 2;
int z = 3;

namespace A{
    namespace B{
        int x = 5;
        int y = 10;
        int z = 0;
    }
    void foo(){
        using namespace A::B;
        std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are not ambiguous
    }
}

namespace AA{
    namespace BB{
        void bar(){
            using namespace A::B;
            std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are ambiguous
        }
    }
}


int main(){

    A::foo(); // works fine
    AA::BB::bar(); // fails to compile

    std::cout << "\ndone!\n";
}

Upvotes: 1

Views: 47

Answers (1)

SergeyA
SergeyA

Reputation: 62553

Yes, this is quite convoluted, but the quote you were giving explains exactly what's going on. In your first example (reduced number of variables to 1):

int x = 1;

namespace A {
    namespace B {
        int x = 5;
    }
    void foo(){
        using namespace A::B;
        std::cout << x << '\n';
    }
}

The nearest namespace would be A. In essence, the code would be equivalent to

int x = 1;

namespace A {
    int x = 5;

    void foo(){
        std::cout << x << '\n'; // x from NS a.
    }
}

x would be a name defined in A and will be used.

In the second example,

namespace AA {
    namespace BB {
        void bar() {
            using namespace A::B;
            std::cout << x << '\n'; 
        }
    }
}

the nearest namespace would be global namespace. In essence, the code would be equivalent to

int x = 1;
int x = 5;

namespace AA {
    namespace BB {
        void bar() {
            std::cout << x << '\n'; 
        }
    }
}

This code would be malformed, since x can't be redefined in the same scope.

Upvotes: 2

Related Questions