- tmp/tmpqod1ct_c/{from.md → to.md} +142 -71
tmp/tmpqod1ct_c/{from.md → to.md}
RENAMED
|
@@ -1,69 +1,64 @@
|
|
| 1 |
### Namespace definition <a id="namespace.def">[[namespace.def]]</a>
|
| 2 |
|
| 3 |
-
The grammar for a *namespace-definition* is
|
| 4 |
-
|
| 5 |
``` bnf
|
| 6 |
namespace-name:
|
| 7 |
-
|
| 8 |
namespace-alias
|
| 9 |
```
|
| 10 |
|
| 11 |
-
``` bnf
|
| 12 |
-
original-namespace-name:
|
| 13 |
-
identifier
|
| 14 |
-
```
|
| 15 |
-
|
| 16 |
``` bnf
|
| 17 |
namespace-definition:
|
| 18 |
named-namespace-definition
|
| 19 |
unnamed-namespace-definition
|
|
|
|
| 20 |
```
|
| 21 |
|
| 22 |
``` bnf
|
| 23 |
named-namespace-definition:
|
| 24 |
-
|
| 25 |
-
extension-namespace-definition
|
| 26 |
-
```
|
| 27 |
-
|
| 28 |
-
``` bnf
|
| 29 |
-
original-namespace-definition:
|
| 30 |
-
'inline'ₒₚₜ 'namespace' identifier '{' namespace-body '}'
|
| 31 |
-
```
|
| 32 |
-
|
| 33 |
-
``` bnf
|
| 34 |
-
extension-namespace-definition:
|
| 35 |
-
'inline'ₒₚₜ 'namespace' original-namespace-name '{' namespace-body '}'
|
| 36 |
```
|
| 37 |
|
| 38 |
``` bnf
|
| 39 |
unnamed-namespace-definition:
|
| 40 |
-
'inline'ₒₚₜ 'namespace {' namespace-body '}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
```
|
| 42 |
|
| 43 |
``` bnf
|
| 44 |
namespace-body:
|
| 45 |
declaration-seqₒₚₜ
|
| 46 |
```
|
| 47 |
|
| 48 |
-
The *identifier* in an *original-namespace-definition* shall not have
|
| 49 |
-
been previously defined in the declarative region in which the
|
| 50 |
-
*original-namespace-definition* appears. The *identifier* in an
|
| 51 |
-
*original-namespace-definition* is the name of the namespace.
|
| 52 |
-
Subsequently in that declarative region, it is treated as an
|
| 53 |
-
*original-namespace-name*.
|
| 54 |
-
|
| 55 |
-
The *original-namespace-name* in an *extension-namespace-definition*
|
| 56 |
-
shall have previously been defined in an *original-namespace-definition*
|
| 57 |
-
in the same declarative region.
|
| 58 |
-
|
| 59 |
Every *namespace-definition* shall appear in the global scope or in a
|
| 60 |
namespace scope ([[basic.scope.namespace]]).
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
Because a *namespace-definition* contains *declaration*s in its
|
| 63 |
*namespace-body* and a *namespace-definition* is itself a *declaration*,
|
| 64 |
-
it follows that *namespace-
|
|
|
|
|
|
|
| 65 |
|
| 66 |
``` cpp
|
| 67 |
namespace Outer {
|
| 68 |
int i;
|
| 69 |
namespace Inner {
|
|
@@ -72,16 +67,20 @@ namespace Outer {
|
|
| 72 |
void g() { i++; } // Inner::i
|
| 73 |
}
|
| 74 |
}
|
| 75 |
```
|
| 76 |
|
|
|
|
|
|
|
| 77 |
The *enclosing namespaces* of a declaration are those namespaces in
|
| 78 |
which the declaration lexically appears, except for a redeclaration of a
|
| 79 |
namespace member outside its original namespace (e.g., a definition as
|
| 80 |
specified in [[namespace.memdef]]). Such a redeclaration has the same
|
| 81 |
enclosing namespaces as the original declaration.
|
| 82 |
|
|
|
|
|
|
|
| 83 |
``` cpp
|
| 84 |
namespace Q {
|
| 85 |
namespace V {
|
| 86 |
void f(); // enclosing namespaces are the global namespace, Q, and Q::V
|
| 87 |
class C { void m(); };
|
|
@@ -92,55 +91,94 @@ namespace Q {
|
|
| 92 |
void V::C::m() { // enclosing namespaces are the global namespace, Q, and Q::V
|
| 93 |
}
|
| 94 |
}
|
| 95 |
```
|
| 96 |
|
|
|
|
|
|
|
| 97 |
If the optional initial `inline` keyword appears in a
|
| 98 |
*namespace-definition* for a particular namespace, that namespace is
|
| 99 |
declared to be an *inline namespace*. The `inline` keyword may be used
|
| 100 |
-
on
|
| 101 |
-
the *
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
|
| 103 |
Members of an inline namespace can be used in most respects as though
|
| 104 |
they were members of the enclosing namespace. Specifically, the inline
|
| 105 |
namespace and its enclosing namespace are both added to the set of
|
| 106 |
associated namespaces used in argument-dependent lookup (
|
| 107 |
[[basic.lookup.argdep]]) whenever one of them is, and a
|
| 108 |
*using-directive* ([[namespace.udir]]) that names the inline namespace
|
| 109 |
is implicitly inserted into the enclosing namespace as for an unnamed
|
| 110 |
namespace ([[namespace.unnamed]]). Furthermore, each member of the
|
| 111 |
-
inline namespace can subsequently be
|
| 112 |
-
[[temp.
|
| 113 |
-
though it were a member
|
| 114 |
-
|
| 115 |
-
[[namespace.qual]]) will include
|
| 116 |
-
in by the *using-directive* even
|
| 117 |
-
in the enclosing namespace.
|
| 118 |
|
| 119 |
These properties are transitive: if a namespace `N` contains an inline
|
| 120 |
namespace `M`, which in turn contains an inline namespace `O`, then the
|
| 121 |
members of `O` can be used as though they were members of `M` or `N`.
|
| 122 |
The *inline namespace set* of `N` is the transitive closure of all
|
| 123 |
inline namespaces in `N`. The *enclosing namespace set* of `O` is the
|
| 124 |
set of namespaces consisting of the innermost non-inline namespace
|
| 125 |
enclosing an inline namespace `O`, together with any intervening inline
|
| 126 |
namespaces.
|
| 127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
#### Unnamed namespaces <a id="namespace.unnamed">[[namespace.unnamed]]</a>
|
| 129 |
|
| 130 |
An *unnamed-namespace-definition* behaves as if it were replaced by
|
| 131 |
|
| 132 |
``` bnf
|
| 133 |
-
'inline'ₒₚₜ 'namespace' unique '{ /* empty body */ }'
|
| 134 |
-
'using namespace' unique ';'
|
| 135 |
-
'namespace' unique '{' namespace-body '}'
|
| 136 |
```
|
| 137 |
|
| 138 |
where `inline` appears if and only if it appears in the
|
| 139 |
-
*unnamed-namespace-definition*
|
| 140 |
translation unit are replaced by the same identifier, and this
|
| 141 |
-
identifier differs from all other identifiers in the
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
|
| 143 |
``` cpp
|
| 144 |
namespace { int i; } // unique ::i
|
| 145 |
void f() { i++; } // unique ::i++
|
| 146 |
|
|
@@ -158,64 +196,95 @@ void h() {
|
|
| 158 |
A::i++; // A::unique ::i
|
| 159 |
j++; // A::unique ::j
|
| 160 |
}
|
| 161 |
```
|
| 162 |
|
|
|
|
|
|
|
| 163 |
#### Namespace member definitions <a id="namespace.memdef">[[namespace.memdef]]</a>
|
| 164 |
|
| 165 |
-
|
| 166 |
-
|
| 167 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
|
| 169 |
``` cpp
|
| 170 |
namespace X {
|
| 171 |
-
void f() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
}
|
| 173 |
```
|
| 174 |
|
|
|
|
|
|
|
| 175 |
Members of a named namespace can also be defined outside that namespace
|
| 176 |
by explicit qualification ([[namespace.qual]]) of the name being
|
| 177 |
defined, provided that the entity being defined was already declared in
|
| 178 |
the namespace and the definition appears after the point of declaration
|
| 179 |
in a namespace that encloses the declaration’s namespace.
|
| 180 |
|
|
|
|
|
|
|
| 181 |
``` cpp
|
| 182 |
namespace Q {
|
| 183 |
namespace V {
|
| 184 |
void f();
|
| 185 |
}
|
| 186 |
-
void V::f() {
|
| 187 |
-
void V::g() {
|
| 188 |
namespace V {
|
| 189 |
void g();
|
| 190 |
}
|
| 191 |
}
|
| 192 |
|
| 193 |
namespace R {
|
| 194 |
-
void Q::V::g() {
|
| 195 |
}
|
| 196 |
```
|
| 197 |
|
| 198 |
-
|
|
|
|
| 199 |
If a `friend` declaration in a non-local class first declares a class,
|
| 200 |
-
function, class template or function template[^
|
| 201 |
of the innermost enclosing namespace. The `friend` declaration does not
|
| 202 |
by itself make the name visible to unqualified lookup (
|
| 203 |
[[basic.lookup.unqual]]) or qualified lookup ([[basic.lookup.qual]]).
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
lookup
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
|
| 218 |
``` cpp
|
| 219 |
// Assume f and g have not yet been declared.
|
| 220 |
void h(int);
|
| 221 |
template <class T> void f2(T);
|
|
@@ -231,12 +300,12 @@ namespace A {
|
|
| 231 |
};
|
| 232 |
|
| 233 |
// A::f, A::g and A::h are not visible here
|
| 234 |
X x;
|
| 235 |
void g() { f(x); } // definition of A::g
|
| 236 |
-
void f(X) {
|
| 237 |
-
void h(int) {
|
| 238 |
// A::f, A::g and A::h are visible here and known to be friends
|
| 239 |
}
|
| 240 |
|
| 241 |
using A::x;
|
| 242 |
|
|
@@ -245,5 +314,7 @@ void h() {
|
|
| 245 |
A::X::f(x); // error: f is not a member of A::X
|
| 246 |
A::X::Y::g(); // error: g is not a member of A::X::Y
|
| 247 |
}
|
| 248 |
```
|
| 249 |
|
|
|
|
|
|
|
|
|
| 1 |
### Namespace definition <a id="namespace.def">[[namespace.def]]</a>
|
| 2 |
|
|
|
|
|
|
|
| 3 |
``` bnf
|
| 4 |
namespace-name:
|
| 5 |
+
identifier
|
| 6 |
namespace-alias
|
| 7 |
```
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
``` bnf
|
| 10 |
namespace-definition:
|
| 11 |
named-namespace-definition
|
| 12 |
unnamed-namespace-definition
|
| 13 |
+
nested-namespace-definition
|
| 14 |
```
|
| 15 |
|
| 16 |
``` bnf
|
| 17 |
named-namespace-definition:
|
| 18 |
+
'inline'ₒₚₜ 'namespace' attribute-specifier-seqₒₚₜ identifier '{' namespace-body '}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
```
|
| 20 |
|
| 21 |
``` bnf
|
| 22 |
unnamed-namespace-definition:
|
| 23 |
+
'inline'ₒₚₜ 'namespace' attribute-specifier-seqₒₚₜ '{' namespace-body '}'
|
| 24 |
+
```
|
| 25 |
+
|
| 26 |
+
``` bnf
|
| 27 |
+
nested-namespace-definition:
|
| 28 |
+
'namespace' enclosing-namespace-specifier '::' identifier '{' namespace-body '}'
|
| 29 |
+
```
|
| 30 |
+
|
| 31 |
+
``` bnf
|
| 32 |
+
enclosing-namespace-specifier:
|
| 33 |
+
identifier
|
| 34 |
+
enclosing-namespace-specifier '::' identifier
|
| 35 |
```
|
| 36 |
|
| 37 |
``` bnf
|
| 38 |
namespace-body:
|
| 39 |
declaration-seqₒₚₜ
|
| 40 |
```
|
| 41 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
Every *namespace-definition* shall appear in the global scope or in a
|
| 43 |
namespace scope ([[basic.scope.namespace]]).
|
| 44 |
|
| 45 |
+
In a *named-namespace-definition*, the *identifier* is the name of the
|
| 46 |
+
namespace. If the *identifier*, when looked up (
|
| 47 |
+
[[basic.lookup.unqual]]), refers to a *namespace-name* (but not a
|
| 48 |
+
*namespace-alias*) that was introduced in the namespace in which the
|
| 49 |
+
*named-namespace-definition* appears or that was introduced in a member
|
| 50 |
+
of the inline namespace set of that namespace, the
|
| 51 |
+
*namespace-definition* *extends* the previously-declared namespace.
|
| 52 |
+
Otherwise, the *identifier* is introduced as a *namespace-name* into the
|
| 53 |
+
declarative region in which the *named-namespace-definition* appears.
|
| 54 |
+
|
| 55 |
Because a *namespace-definition* contains *declaration*s in its
|
| 56 |
*namespace-body* and a *namespace-definition* is itself a *declaration*,
|
| 57 |
+
it follows that *namespace-definition*s can be nested.
|
| 58 |
+
|
| 59 |
+
[*Example 1*:
|
| 60 |
|
| 61 |
``` cpp
|
| 62 |
namespace Outer {
|
| 63 |
int i;
|
| 64 |
namespace Inner {
|
|
|
|
| 67 |
void g() { i++; } // Inner::i
|
| 68 |
}
|
| 69 |
}
|
| 70 |
```
|
| 71 |
|
| 72 |
+
— *end example*]
|
| 73 |
+
|
| 74 |
The *enclosing namespaces* of a declaration are those namespaces in
|
| 75 |
which the declaration lexically appears, except for a redeclaration of a
|
| 76 |
namespace member outside its original namespace (e.g., a definition as
|
| 77 |
specified in [[namespace.memdef]]). Such a redeclaration has the same
|
| 78 |
enclosing namespaces as the original declaration.
|
| 79 |
|
| 80 |
+
[*Example 2*:
|
| 81 |
+
|
| 82 |
``` cpp
|
| 83 |
namespace Q {
|
| 84 |
namespace V {
|
| 85 |
void f(); // enclosing namespaces are the global namespace, Q, and Q::V
|
| 86 |
class C { void m(); };
|
|
|
|
| 91 |
void V::C::m() { // enclosing namespaces are the global namespace, Q, and Q::V
|
| 92 |
}
|
| 93 |
}
|
| 94 |
```
|
| 95 |
|
| 96 |
+
— *end example*]
|
| 97 |
+
|
| 98 |
If the optional initial `inline` keyword appears in a
|
| 99 |
*namespace-definition* for a particular namespace, that namespace is
|
| 100 |
declared to be an *inline namespace*. The `inline` keyword may be used
|
| 101 |
+
on a *namespace-definition* that extends a namespace only if it was
|
| 102 |
+
previously used on the *namespace-definition* that initially declared
|
| 103 |
+
the *namespace-name* for that namespace.
|
| 104 |
+
|
| 105 |
+
The optional *attribute-specifier-seq* in a *named-namespace-definition*
|
| 106 |
+
appertains to the namespace being defined or extended.
|
| 107 |
|
| 108 |
Members of an inline namespace can be used in most respects as though
|
| 109 |
they were members of the enclosing namespace. Specifically, the inline
|
| 110 |
namespace and its enclosing namespace are both added to the set of
|
| 111 |
associated namespaces used in argument-dependent lookup (
|
| 112 |
[[basic.lookup.argdep]]) whenever one of them is, and a
|
| 113 |
*using-directive* ([[namespace.udir]]) that names the inline namespace
|
| 114 |
is implicitly inserted into the enclosing namespace as for an unnamed
|
| 115 |
namespace ([[namespace.unnamed]]). Furthermore, each member of the
|
| 116 |
+
inline namespace can subsequently be partially specialized (
|
| 117 |
+
[[temp.class.spec]]), explicitly instantiated ([[temp.explicit]]), or
|
| 118 |
+
explicitly specialized ([[temp.expl.spec]]) as though it were a member
|
| 119 |
+
of the enclosing namespace. Finally, looking up a name in the enclosing
|
| 120 |
+
namespace via explicit qualification ([[namespace.qual]]) will include
|
| 121 |
+
members of the inline namespace brought in by the *using-directive* even
|
| 122 |
+
if there are declarations of that name in the enclosing namespace.
|
| 123 |
|
| 124 |
These properties are transitive: if a namespace `N` contains an inline
|
| 125 |
namespace `M`, which in turn contains an inline namespace `O`, then the
|
| 126 |
members of `O` can be used as though they were members of `M` or `N`.
|
| 127 |
The *inline namespace set* of `N` is the transitive closure of all
|
| 128 |
inline namespaces in `N`. The *enclosing namespace set* of `O` is the
|
| 129 |
set of namespaces consisting of the innermost non-inline namespace
|
| 130 |
enclosing an inline namespace `O`, together with any intervening inline
|
| 131 |
namespaces.
|
| 132 |
|
| 133 |
+
A *nested-namespace-definition* with an *enclosing-namespace-specifier*
|
| 134 |
+
`E`, *identifier* `I` and *namespace-body* `B` is equivalent to
|
| 135 |
+
|
| 136 |
+
``` cpp
|
| 137 |
+
namespace E { namespace I { B } }
|
| 138 |
+
```
|
| 139 |
+
|
| 140 |
+
[*Example 3*:
|
| 141 |
+
|
| 142 |
+
``` cpp
|
| 143 |
+
namespace A::B::C {
|
| 144 |
+
int i;
|
| 145 |
+
}
|
| 146 |
+
```
|
| 147 |
+
|
| 148 |
+
The above has the same effect as:
|
| 149 |
+
|
| 150 |
+
``` cpp
|
| 151 |
+
namespace A {
|
| 152 |
+
namespace B {
|
| 153 |
+
namespace C {
|
| 154 |
+
int i;
|
| 155 |
+
}
|
| 156 |
+
}
|
| 157 |
+
}
|
| 158 |
+
```
|
| 159 |
+
|
| 160 |
+
— *end example*]
|
| 161 |
+
|
| 162 |
#### Unnamed namespaces <a id="namespace.unnamed">[[namespace.unnamed]]</a>
|
| 163 |
|
| 164 |
An *unnamed-namespace-definition* behaves as if it were replaced by
|
| 165 |
|
| 166 |
``` bnf
|
| 167 |
+
'inline'ₒₚₜ 'namespace' 'unique ' '{ /* empty body */ }'
|
| 168 |
+
'using namespace' 'unique ' ';'
|
| 169 |
+
'namespace' 'unique ' '{' namespace-body '}'
|
| 170 |
```
|
| 171 |
|
| 172 |
where `inline` appears if and only if it appears in the
|
| 173 |
+
*unnamed-namespace-definition* and all occurrences of `unique ` in a
|
| 174 |
translation unit are replaced by the same identifier, and this
|
| 175 |
+
identifier differs from all other identifiers in the translation unit.
|
| 176 |
+
The optional *attribute-specifier-seq* in the
|
| 177 |
+
*unnamed-namespace-definition* appertains to `unique `.
|
| 178 |
+
|
| 179 |
+
[*Example 1*:
|
| 180 |
|
| 181 |
``` cpp
|
| 182 |
namespace { int i; } // unique ::i
|
| 183 |
void f() { i++; } // unique ::i++
|
| 184 |
|
|
|
|
| 196 |
A::i++; // A::unique ::i
|
| 197 |
j++; // A::unique ::j
|
| 198 |
}
|
| 199 |
```
|
| 200 |
|
| 201 |
+
— *end example*]
|
| 202 |
+
|
| 203 |
#### Namespace member definitions <a id="namespace.memdef">[[namespace.memdef]]</a>
|
| 204 |
|
| 205 |
+
A declaration in a namespace `N` (excluding declarations in nested
|
| 206 |
+
scopes) whose *declarator-id* is an *unqualified-id* ([[dcl.meaning]]),
|
| 207 |
+
whose *class-head-name* (Clause [[class]]) or *enum-head-name* (
|
| 208 |
+
[[dcl.enum]]) is an *identifier*, or whose *elaborated-type-specifier*
|
| 209 |
+
is of the form *class-key* *attribute-specifier-seq*ₒₚₜ *identifier* (
|
| 210 |
+
[[dcl.type.elab]]), or that is an *opaque-enum-declaration*, declares
|
| 211 |
+
(or redeclares) its *unqualified-id* or *identifier* as a member of `N`.
|
| 212 |
+
|
| 213 |
+
[*Note 1*: An explicit instantiation ([[temp.explicit]]) or explicit
|
| 214 |
+
specialization ([[temp.expl.spec]]) of a template does not introduce a
|
| 215 |
+
name and thus may be declared using an *unqualified-id* in a member of
|
| 216 |
+
the enclosing namespace set, if the primary template is declared in an
|
| 217 |
+
inline namespace. — *end note*]
|
| 218 |
+
|
| 219 |
+
[*Example 1*:
|
| 220 |
|
| 221 |
``` cpp
|
| 222 |
namespace X {
|
| 223 |
+
void f() { ... } // OK: introduces X::f()
|
| 224 |
+
|
| 225 |
+
namespace M {
|
| 226 |
+
void g(); // OK: introduces X::M::g()
|
| 227 |
+
}
|
| 228 |
+
using M::g;
|
| 229 |
+
void g(); // error: conflicts with X::M::g()
|
| 230 |
}
|
| 231 |
```
|
| 232 |
|
| 233 |
+
— *end example*]
|
| 234 |
+
|
| 235 |
Members of a named namespace can also be defined outside that namespace
|
| 236 |
by explicit qualification ([[namespace.qual]]) of the name being
|
| 237 |
defined, provided that the entity being defined was already declared in
|
| 238 |
the namespace and the definition appears after the point of declaration
|
| 239 |
in a namespace that encloses the declaration’s namespace.
|
| 240 |
|
| 241 |
+
[*Example 2*:
|
| 242 |
+
|
| 243 |
``` cpp
|
| 244 |
namespace Q {
|
| 245 |
namespace V {
|
| 246 |
void f();
|
| 247 |
}
|
| 248 |
+
void V::f() { ... } // OK
|
| 249 |
+
void V::g() { ... } // error: g() is not yet a member of V
|
| 250 |
namespace V {
|
| 251 |
void g();
|
| 252 |
}
|
| 253 |
}
|
| 254 |
|
| 255 |
namespace R {
|
| 256 |
+
void Q::V::g() { ... } // error: R doesn't enclose Q
|
| 257 |
}
|
| 258 |
```
|
| 259 |
|
| 260 |
+
— *end example*]
|
| 261 |
+
|
| 262 |
If a `friend` declaration in a non-local class first declares a class,
|
| 263 |
+
function, class template or function template[^5] the friend is a member
|
| 264 |
of the innermost enclosing namespace. The `friend` declaration does not
|
| 265 |
by itself make the name visible to unqualified lookup (
|
| 266 |
[[basic.lookup.unqual]]) or qualified lookup ([[basic.lookup.qual]]).
|
| 267 |
+
|
| 268 |
+
[*Note 2*: The name of the friend will be visible in its namespace if a
|
| 269 |
+
matching declaration is provided at namespace scope (either before or
|
| 270 |
+
after the class definition granting friendship). — *end note*]
|
| 271 |
+
|
| 272 |
+
If a friend function or function template is called, its name may be
|
| 273 |
+
found by the name lookup that considers functions from namespaces and
|
| 274 |
+
classes associated with the types of the function arguments (
|
| 275 |
+
[[basic.lookup.argdep]]). If the name in a `friend` declaration is
|
| 276 |
+
neither qualified nor a *template-id* and the declaration is a function
|
| 277 |
+
or an *elaborated-type-specifier*, the lookup to determine whether the
|
| 278 |
+
entity has been previously declared shall not consider any scopes
|
| 279 |
+
outside the innermost enclosing namespace.
|
| 280 |
+
|
| 281 |
+
[*Note 3*: The other forms of `friend` declarations cannot declare a
|
| 282 |
+
new member of the innermost enclosing namespace and thus follow the
|
| 283 |
+
usual lookup rules. — *end note*]
|
| 284 |
+
|
| 285 |
+
[*Example 3*:
|
| 286 |
|
| 287 |
``` cpp
|
| 288 |
// Assume f and g have not yet been declared.
|
| 289 |
void h(int);
|
| 290 |
template <class T> void f2(T);
|
|
|
|
| 300 |
};
|
| 301 |
|
| 302 |
// A::f, A::g and A::h are not visible here
|
| 303 |
X x;
|
| 304 |
void g() { f(x); } // definition of A::g
|
| 305 |
+
void f(X) { ... } // definition of A::f
|
| 306 |
+
void h(int) { ... } // definition of A::h
|
| 307 |
// A::f, A::g and A::h are visible here and known to be friends
|
| 308 |
}
|
| 309 |
|
| 310 |
using A::x;
|
| 311 |
|
|
|
|
| 314 |
A::X::f(x); // error: f is not a member of A::X
|
| 315 |
A::X::Y::g(); // error: g is not a member of A::X::Y
|
| 316 |
}
|
| 317 |
```
|
| 318 |
|
| 319 |
+
— *end example*]
|
| 320 |
+
|