During unqualified name lookup, the names
appear as if they were declared in the nearest enclosing namespace which
contains both the using-directive and the nominated
namespace.
[Example 1: namespace A {int i;
namespace B {namespace C {int i;
}usingnamespace A::B::C;
void f1(){
i =5; // OK, C::i visible in B and hides A::i}}namespace D {usingnamespace B;
usingnamespace C;
void f2(){
i =5; // ambiguous, B::C::i or A::i?}}void f3(){
i =5; // uses A::i}}void f4(){
i =5; // error: neither i is visible} — end example]
[Example 2: namespace M {int i;
}namespace N {int i;
usingnamespace M;
}void f(){usingnamespace N;
i =7; // error: both M::i and N::i are visible}
For another example,
namespace A {int i;
}namespace B {int i;
int j;
namespace C {namespace D {usingnamespace A;
int j;
int k;
int a = i; // B::i hides A::i}usingnamespace D;
int k =89; // no problem yetint l = k; // ambiguous: C::k or D::kint m = i; // B::i hides A::iint n = j; // D::j hides B::j}}
If name lookup finds a declaration for a name in two different
namespaces, and the declarations do not declare the same entity and do
not declare functions or function templates, the use of the name is ill-formed ([basic.lookup]).
In particular, the name of a variable, function or enumerator does not
hide the name of a class or enumeration declared in a different
namespace.
For example,
namespace A {class X {};
extern"C"int g();
extern"C++"int h();
}namespace B {void X(int);
extern"C"int g();
extern"C++"int h(int);
}usingnamespace A;
usingnamespace B;
void f(){
X(1); // error: name X found in two namespaces
g(); // OK, name g refers to the same entity
h(); // OK, overload resolution selects A::h} — end note]
The order in which namespaces are considered and the
relationships among the namespaces implied by the
using-directives do not affect overload resolution.
Neither is any function excluded because another has the same
signature, even if one is in a namespace reachable through
using-directives in the namespace of the other.87
— end note]
[Example 3: namespace D {int d1;
void f(char);
}usingnamespace D;
int d1; // OK, no conflict with D::d1namespace E {int e;
void f(int);
}namespace D {// namespace extensionint d2;
usingnamespace 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)} — end example]
During
name lookup in a class hierarchy, some ambiguities can be
resolved by considering whether one member hides the other along some
paths ([class.member.lookup]).
There is no such disambiguation when
considering the set of names found as a result of following
using-directives.