Files
2025-10-25 03:02:53 +03:00

144 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.4Using namespace directive[namespace.udir]")
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt using namespace [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]") ;
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt using namespace [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice 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.6Splice 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.3Qualified names[expr.prim.id.qual]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1General[namespace.def.general]"), and[*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice 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.4Using 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.1General[namespace.def.general]") in a[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]"), only namespace names are considered,
see [[basic.lookup.udir]](basic.lookup.udir "6.5.7Using-directives and namespace aliases")[.](#2.sentence-2)
— *end note*]
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") appertains to the [*using-directive*](#nt:using-directive "9.9.4Using 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.4Using 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.4Using namespace directive[namespace.udir]") appears after
the [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3Unqualified name lookup"), [[namespace.qual]](namespace.qual "6.5.5.3Namespace 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.4Using 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.4Using 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.4Using namespace directive[namespace.udir]") is transitive: if a scope contains a[*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") that designates a namespace that itself
contains [*using-directive*](#nt:using-directive "9.9.4Using namespace directive[namespace.udir]")*s*, the namespaces designated by those[*using-directive*](#nt:using-directive "9.9.4Using 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.4Using namespace directive[namespace.udir]") for that namespace
can be found through that [*using-directive*](#nt:using-directive "9.9.4Using 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.5Name 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.4Using 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.4Using 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.2Member 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.4Using namespace directive[namespace.udir]")*s*[.](#footnote-83.sentence-2)