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

151 lines
11 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.def]
# 9 Declarations [[dcl]](./#dcl)
## 9.9 Namespaces [[basic.namespace]](basic.namespace#namespace.def)
### 9.9.2 Namespace definition [namespace.def]
#### [9.9.2.1](#general) General [[namespace.def.general]](namespace.def.general)
[namespace-name:](#nt:namespace-name "9.9.2.1General[namespace.def.general]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*namespace-alias*](namespace.alias#nt:namespace-alias "9.9.3Namespace alias[namespace.alias]")
[namespace-definition:](#nt:namespace-definition "9.9.2.1General[namespace.def.general]")
[*named-namespace-definition*](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]")
[*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]")
[*nested-namespace-definition*](#nt:nested-namespace-definition "9.9.2.1General[namespace.def.general]")
[named-namespace-definition:](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]")
inlineopt namespace [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
[unnamed-namespace-definition:](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]")
inlineopt namespace [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")opt { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
[nested-namespace-definition:](#nt:nested-namespace-definition "9.9.2.1General[namespace.def.general]")
namespace [*enclosing-namespace-specifier*](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]") :: inlineopt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
[enclosing-namespace-specifier:](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[*enclosing-namespace-specifier*](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]") :: inlineopt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[namespace-body:](#nt:namespace-body "9.9.2.1General[namespace.def.general]")
[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1Preamble[dcl.pre]")opt
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8270)
Every [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") shall inhabit a namespace scope ([[basic.scope.namespace]](basic.scope.namespace "6.4.6Namespace scope"))[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8273)
In a [*named-namespace-definition*](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]") D,
the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is the name of the namespace[.](#general-2.sentence-1)
The [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is looked up
by searching for it in the scopes of the namespace A in which D appears
and of every element of the inline namespace set of A[.](#general-2.sentence-2)
If the lookup finds a [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for a namespace N,D [*extends*](#def:namespace,extend "9.9.2.1General[namespace.def.general]") N,
and the target scope of D is the scope to which N belongs[.](#general-2.sentence-3)
If the lookup finds nothing, the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is introduced
as a [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]") into A[.](#general-2.sentence-4)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8287)
Because a [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") contains[*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]")*s* in its [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") and a[*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") is itself a [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]"), it
follows that [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]")*s* can be nested[.](#general-3.sentence-1)
[*Example [1](#general-example-1)*: namespace Outer {int i; namespace Inner {void f() { i++; } // Outer::iint i; void g() { i++; } // Inner::i}} — *end example*]
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8305)
If the optional initial inline keyword appears in a[*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") for a particular namespace, that namespace is
declared to be an [*inline namespace*](#def:namespace,inline "9.9.2.1General[namespace.def.general]")[.](#general-4.sentence-1)
The inline keyword may be
used on a [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") that extends a namespace
only if it was previously used on the [*namespace-definition*](#nt:namespace-definition "9.9.2.1General[namespace.def.general]") that initially declared the [*namespace-name*](#nt:namespace-name "9.9.2.1General[namespace.def.general]") for that namespace[.](#general-4.sentence-2)
[5](#general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8313)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in a [*named-namespace-definition*](#nt:named-namespace-definition "9.9.2.1General[namespace.def.general]") appertains to the namespace being defined or extended[.](#general-5.sentence-1)
[6](#general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8318)
Members of an inline namespace can be used in most respects as though they were members
of the innermost enclosing namespace[.](#general-6.sentence-1)
Specifically, the inline namespace and its enclosing
namespace are both added to the set of associated namespaces used in[argument-dependent lookup](basic.lookup.argdep "6.5.4Argument-dependent name lookup[basic.lookup.argdep]") whenever one of them is,
and a [*using-directive*](namespace.udir#nt:using-directive "9.9.4Using namespace directive[namespace.udir]") ([[namespace.udir]](namespace.udir "9.9.4Using namespace directive")) that names the inline
namespace is implicitly inserted into the enclosing namespace as for an unnamed
namespace ([[namespace.unnamed]](#namespace.unnamed "9.9.2.2Unnamed namespaces"))[.](#general-6.sentence-2)
Furthermore, each
member of the inline namespace can subsequently be partially
specialized ([[temp.spec.partial]](temp.spec.partial "13.7.6Partial specialization")), explicitly
instantiated ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation")), or explicitly specialized ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit specialization")) as
though it were a member of the enclosing namespace[.](#general-6.sentence-3)
Finally, looking up a name in the
enclosing namespace via explicit qualification ([[namespace.qual]](namespace.qual "6.5.5.3Namespace members")) will include
members of the inline namespace even if
there are declarations of that name in the enclosing namespace[.](#general-6.sentence-4)
[7](#general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8334)
These properties are transitive: if a namespace N contains an inline namespaceM, which in turn contains an inline namespace O, then the members ofO can be used as though they were members of M or N[.](#general-7.sentence-1)
The [*inline namespace set*](#def:inline_namespace_set "9.9.2.1General[namespace.def.general]") of N is the transitive closure of all
inline namespaces in N[.](#general-7.sentence-2)
[8](#general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8341)
A [*nested-namespace-definition*](#nt:nested-namespace-definition "9.9.2.1General[namespace.def.general]") with an[*enclosing-namespace-specifier*](#nt:enclosing-namespace-specifier "9.9.2.1General[namespace.def.general]") E,[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") I and[*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") B is equivalent tonamespace E { inlineopt namespace I { B } } where the optional inline is present if and only if
the [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") I is preceded by inline[.](#general-8.sentence-1)
[*Example [2](#general-example-2)*: namespace A::inline B::C {int i;}
The above has the same effect as:namespace A {inline namespace B {namespace C {int i; }}}
— *end example*]
#### [9.9.2.2](#namespace.unnamed) Unnamed namespaces [[namespace.unnamed]](namespace.unnamed)
[1](#namespace.unnamed-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L8373)
An [*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") behaves as if it were
replaced by
inlineopt namespace *unique* { /* empty body */ }
using namespace *unique* ;
namespace *unique* { [*namespace-body*](#nt:namespace-body "9.9.2.1General[namespace.def.general]") }
whereinline appears if and only if it appears in the[*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") and all occurrences of *unique* in a translation unit are replaced by
the same identifier, and this identifier differs from all other
identifiers in the program[.](#namespace.unnamed-1.sentence-1)
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") in the [*unnamed-namespace-definition*](#nt:unnamed-namespace-definition "9.9.2.1General[namespace.def.general]") appertains to *unique*[.](#namespace.unnamed-1.sentence-2)
[*Example [1](#namespace.unnamed-example-1)*: namespace { int i; } // *unique*::ivoid f() { i++; } // *unique*::i++namespace A {namespace {int i; // A::*unique*::iint j; // A::*unique*::j}void g() { i++; } // A::*unique*::i++}using namespace A;void h() { i++; // error: *unique*::i or A::*unique*::i A::i++; // A::*unique*::i j++; // A::*unique*::j} — *end example*]