using-directive: attribute-specifier-seqopt using namespace nested-name-specifieropt namespace-name ;
A using-directive shall not appear in class scope, but may appear in namespace scope or in block scope. [ Note: When looking up a namespace-name in a using-directive, only namespace names are considered, see [basic.lookup.udir]. — end note ] The optional attribute-specifier-seq appertains to the using-directive.
A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. 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. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]
A using-directive does not add any members to the declarative region in which it appears. [ Example:
namespace A { int i; namespace B { namespace C { int i; } using namespace A::B::C; void f1() { i = 5; // OK, C::i visible in B and hides A::i } } namespace D { using namespace B; using namespace C; void f2() { i = 5; // ambiguous, B::C::i or A::i? } } void f3() { i = 5; // uses A::i } } void f4() { i = 5; // ill-formed; neither i is visible }
— end example ]
For unqualified lookup, the using-directive is transitive: if a scope contains a using-directive that nominates a second namespace that itself contains using-directives, the effect is as if the using-directives from the second namespace also appeared in the first. [ Note: For qualified lookup, see [namespace.qual]. — end note ] [ Example:
namespace M {
int i;
}
namespace N {
int i;
using namespace M;
}
void f() {
using namespace 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 { using namespace A; int j; int k; int a = i; // B::i hides A::i } using namespace D; int k = 89; // no problem yet int l = k; // ambiguous: C::k or D::k int m = i; // B::i hides A::i int n = j; // D::j hides B::j } }
— end example ]
If a namespace is extended after a using-directive for that namespace is given, the additional members of the extended namespace and the members of namespaces nominated by using-directives in the extending namespace-definition can be used after the extending namespace-definition.
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, the use of the name is ill-formed. [ Note: 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); } using namespace A; using namespace 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 ]
During overload resolution, all functions from the transitive search are considered for argument matching. The set of declarations found by the transitive search is unordered. [ Note: In particular, the order in which namespaces were considered and the relationships among the namespaces implied by the using-directives do not cause preference to be given to any of the declarations found by the search. — end note ] An ambiguity exists if the best match finds two functions with the same signature, even if one is in a namespace reachable through using-directives in the namespace of the other.99 [ Example:
namespace D { int d1; void f(char); } using namespace D; int d1; // OK: 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) }
— end example ]
During name lookup in a class hierarchy, some ambiguities may 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.