Reputation: 2552
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:
- 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";
}
Why the first version works fine (function A::foo()
) but not the second version (AA::BB::bar()
)?
I find it a bit confusing 'injecting names into the nearest namespace that the using directive and the namespace definition'.
Upvotes: 1
Views: 47
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