[basic.namespace] (original) (raw)
A namespace is an optionally-named declarative region.
The name of a namespace can be used to access entities declared in that namespace; that is, the members of the namespace.
Unlike other declarative regions, the definition of a namespace can be split over several parts of one or more translation units.
9.8.1 Namespace definition [namespace.def]
namespace-name: identifier namespace-alias
namespace-definition: named-namespace-definition unnamed-namespace-definition nested-namespace-definition
named-namespace-definition: inline namespace attribute-specifier-seq identifier { namespace-body }
unnamed-namespace-definition: inline namespace attribute-specifier-seq { namespace-body }
nested-namespace-definition: namespace enclosing-namespace-specifier :: inline identifier { namespace-body }
enclosing-namespace-specifier: identifier enclosing-namespace-specifier :: inline identifier
namespace-body: declaration-seq
In a named-namespace-definition, the identifier is the name of the namespace.
If the identifier, when looked up, refers to a namespace-name (but not a namespace-alias) that was introduced in the namespace in which the named-namespace-definition appears or that was introduced in a member of the inline namespace set of that namespace, the namespace-definition extends the previously-declared namespace.
Otherwise, the identifier is introduced as a namespace-name into the declarative region in which the named-namespace-definition appears.
Because a namespace-definition containsdeclarations in its namespace-body and anamespace-definition is itself a declaration, it follows that namespace-definitions can be nested.
[ Example
:
namespace Outer {
int i;
namespace Inner {
void f() { i++; }
int i;
void g() { i++; }
}
}
— end example
]
The enclosing namespaces of a declaration are those namespaces in which the declaration lexically appears, except for a redeclaration of a namespace member outside its original namespace (e.g., a definition as specified in [namespace.memdef]).
Such a redeclaration has the same enclosing namespaces as the original declaration.
[ Example
:
namespace Q {
namespace V {
void f();
class C { void m(); };
}
void V::f() {
extern void h();
}
void V::C::m() {
}
}
— end example
]
If the optional initial inline keyword appears in anamespace-definition for a particular namespace, that namespace is declared to be an inline namespace.
The inline keyword may be used on a namespace-definition that extends a namespace only if it was previously used on the namespace-definitionthat initially declared the namespace-name for that namespace.
Members of an inline namespace can be used in most respects as though they were members of the enclosing namespace.
Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces used inargument-dependent lookup whenever one of them is, and a using-directive that names the inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace.
Finally, looking up a name in the enclosing namespace via explicit qualification ([namespace.qual]) will include members of the inline namespace brought in by the using-directive even if there are declarations of that name in the enclosing namespace.
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.
The inline namespace set of N is the transitive closure of all inline namespaces in N.
The enclosing namespace set of O is the set of namespaces consisting of the innermost non-inline namespace enclosing an inline namespace O, together with any intervening inline namespaces.
A nested-namespace-definition with anenclosing-namespace-specifier E,identifier I andnamespace-body Bis equivalent to
namespace E { inline namespace I { B } }
where the optional inline is present if and only if the identifier I is preceded by inline.
[ Example
:
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.8.1.1 Unnamed namespaces [namespace.unnamed]
An unnamed-namespace-definition behaves as if it were replaced by
inline namespace unique { } using namespace unique ; namespace unique { namespace-body }
whereinline appears if and only if it appears in theunnamed-namespace-definitionand all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the translation unit.
[ Example
:
namespace { int i; }
void f() { i++; }
namespace A {
namespace {
int i;
int j;
}
void g() { i++; }
}
using namespace A;
void h() {
i++;
A::i++;
j++;
}
— end example
]
9.8.1.2 Namespace member definitions [namespace.memdef]
[ Example
:
namespace X { void f() { }
namespace M {
void g();
}
using M::g;
void g();
}
— end example
]
Members of a named namespace can also be defined outside that namespace by explicit qualification ([namespace.qual]) of the name being defined, provided that the entity being defined was already declared in the namespace and the definition appears after the point of declaration in a namespace that encloses the declaration's namespace.
[ Example
:
namespace Q {
namespace V {
void f();
}
void V::f() { }
void V::g() { }
namespace V {
void g();
}
}
namespace R {
void Q::V::g() { }
}
— end example
]
If a friend declaration in a non-local class first declares a class, function, class template or function template95the friend is a member of the innermost enclosing namespace.
[ Note
:
The name of the friend will be visible in its namespace if a matching declaration is provided at namespace scope (either before or after the class definition granting friendship).
— end note
]
If a friend function or function template is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments ([basic.lookup.argdep]).
If the name in a friend declaration is neither qualified nor atemplate-id and the declaration is a function or anelaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.
[ Note
:
The other forms of friend declarations cannot declare a new member of the innermost enclosing namespace and thus follow the usual lookup rules.
— end note
]
[ Example
:
void h(int);
template void f2(T);
namespace A {
class X {
friend void f(X);
class Y {
friend void g();
friend void h(int);
friend void f2<>(int);
};};
X x;
void g() { f(x); }
void f(X) { }
void h(int) { }
}
using A::x;
void h() {
A::f(x);
A::X::f(x);
A::X::Y::g();
}
— end example
]
9.8.2 Namespace alias [namespace.alias]
The identifier in a namespace-alias-definition is a synonym for the name of the namespace denoted by thequalified-namespace-specifier and becomes anamespace-alias.
In a declarative region, a namespace-alias-definition can be used to redefine a namespace-alias declared in that declarative region to refer only to the namespace to which it already refers.
[ Example
:
The following declarations are well-formed:
namespace Company_with_very_long_name { }
namespace CWVLN = Company_with_very_long_name;
namespace CWVLN = Company_with_very_long_name;
namespace CWVLN = CWVLN;
— end example
]
9.8.3 Using namespace directive [namespace.udir]
using-directive: attribute-specifier-seq using namespace nested-name-specifier namespace-name ;
A using-directive shall not appear in class scope, but may appear in namespace scope or in block scope.
A using-directive specifies that the names in the nominated namespace can be used in the scope in which theusing-directive appears after the using-directive.
During unqualified name lookup ([basic.lookup.unqual]), 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;
}
}
namespace D {
using namespace B;
using namespace C;
void f2() {
i = 5;
}
}
void f3() {
i = 5;
}
}
void f4() {
i = 5;
}
— end example
]
For unqualified lookup ([basic.lookup.unqual]), theusing-directive is transitive: if a scope contains ausing-directive that nominates a second namespace that itself contains using-directives, the effect is as if theusing-directives from the second namespace also appeared in the first.
[ Example
:
namespace M { int i; }
namespace N { int i; using namespace M; }
void f() {
using namespace N;
i = 7;
}
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;
}
using namespace D;
int k = 89;
int l = k;
int m = i;
int n = j;
}
}
— end example
]
If a namespace is extended ([namespace.def]) after ausing-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.
[ Note
:
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); } using namespace A; using namespace B;
void f() {
X(1);
g();
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 theusing-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 throughusing-directives in the namespace of the other.96
[ Example
:
namespace D { int d1; void f(char); } using namespace D;
int d1;
namespace E { int e; void f(int); }
namespace D {
int d2;
using namespace E;
void f(int);
}
void f() {
d1++;
::d1++;
D::d1++;
d2++;
e++;
f(1);
f('a');
}
— end example
]