144 lines
8.8 KiB
Markdown
144 lines
8.8 KiB
Markdown
[namespace.udir]
|
||
|
||
# 9 Declarations [[dcl]](./#dcl)
|
||
|
||
## 9.9 Namespaces [[basic.namespace]](basic.namespace#namespace.udir)
|
||
|
||
### 9.9.4 Using namespace directive [namespace.udir]
|
||
|
||
[using-directive:](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")
|
||
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt using namespace [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") ;
|
||
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt using namespace [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") ;
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8464)
|
||
|
||
The [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") (if any) shall designate a namespace
|
||
that is not the global namespace[.](#1.sentence-1)
|
||
|
||
The [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"), and[*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") shall not be dependent[.](#1.sentence-2)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8472)
|
||
|
||
A [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") shall not appear in class scope, but may
|
||
appear in namespace scope or in block scope[.](#2.sentence-1)
|
||
|
||
[*Note [1](#note-1)*:
|
||
|
||
When looking up a [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") in a[*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]"), only namespace names are considered,
|
||
see [[basic.lookup.udir]](basic.lookup.udir "6.5.7 Using-directives and namespace aliases")[.](#2.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")[.](#2.sentence-3)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8482)
|
||
|
||
[*Note [2](#note-2)*:
|
||
|
||
A [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") makes the names in the designated
|
||
namespace usable in the scope in which the[*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") appears after
|
||
the [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup"), [[namespace.qual]](namespace.qual "6.5.5.3 Namespace members"))[.](#3.sentence-1)
|
||
|
||
During unqualified name lookup, the names
|
||
appear as if they were declared in the nearest enclosing namespace which
|
||
contains both the [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") and the designated
|
||
namespace[.](#3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8494)
|
||
|
||
[*Note [3](#note-3)*:
|
||
|
||
A [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") does not introduce any names[.](#4.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#example-1)*: 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; // error: neither i is visible} â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8528)
|
||
|
||
[*Note [4](#note-4)*:
|
||
|
||
A [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") is transitive: if a scope contains a[*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") that designates a namespace that itself
|
||
contains [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")*s*, the namespaces designated by those[*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")*s* are also eligible to be considered[.](#5.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#example-2)*: 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 yetint l = k; // ambiguous: C::k or D::kint m = i; // B::i hides A::iint n = j; // D::j hides B::j}}
|
||
|
||
â *end example*]
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8578)
|
||
|
||
[*Note [5](#note-5)*:
|
||
|
||
Declarations in a namespace
|
||
that appear after a [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") for that namespace
|
||
can be found through that [*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") after they appear[.](#6.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8585)
|
||
|
||
[*Note [6](#note-6)*:
|
||
|
||
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]](basic.lookup "6.5 Name lookup"))[.](#7.sentence-1)
|
||
|
||
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[.](#7.sentence-2)
|
||
|
||
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*]
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8615)
|
||
|
||
[*Note [7](#note-7)*:
|
||
|
||
The order in which namespaces are considered and the
|
||
relationships among the namespaces implied by the[*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")*s* do not affect overload resolution[.](#8.sentence-1)
|
||
|
||
Neither is any function excluded because another has the same
|
||
signature, even if one is in a namespace reachable through[*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")*s* in the namespace of the other[.](#8.sentence-2)[83](#footnote-83 "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.")
|
||
|
||
â *end note*]
|
||
|
||
[*Example [3](#example-3)*: namespace D {int d1; void f(char);}using namespace D;
|
||
|
||
int d1; // OK, no conflict with D::d1namespace E {int e; void f(int);}namespace D { // namespace extensionint 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*]
|
||
|
||
[83)](#footnote-83)[83)](#footnoteref-83)
|
||
|
||
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]](class.member.lookup "6.5.2 Member name lookup"))[.](#footnote-83.sentence-1)
|
||
|
||
There is no such disambiguation when
|
||
considering the set of names found as a result of following[*using-directive*](#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]")*s*[.](#footnote-83.sentence-2)
|