According to 7.3.1.2 Namespace member definitions in C++ Standard ISO/IEC 14882:2003(E)
Every name first declared in a namespace is a member of that namespace. If a friend declaration in a non-local class first declares a class or function (this implies that the name of the class or function is unqualified) the friend class or function is a member of the innermost enclosing namespace.
// Assume f and g have not yet been defined.
void h(int);
template <class T> void f2(T);
namespace A {
class X {
friend void f(X); // A::f(X) is a friend
class Y {
friend void g(); // A::g is a friend
friend void h(int); // A::h is a friend
// ::h not considered
friend void f2<>(int); // ::f2<>(int) is a friend
};
};
// A::f, A::g and A::h are not visible here
X x;
void g() { f(x); } // definition of A::g
void f(X) { /* ... */} // definition of A::f
void h(int) { /* ... */ } // definition of A::h
// A::f, A::g and A::h are visible here and known to be friends
}
Since void h(int);
is first declared in the global namespace, it is a member of the global namespace. Why does the friend declaration friend void h(int);
in class Y
consider A::h
rather than ::h
?
At the end of the paragraph it states:
When looking for a prior declaration of a class or a function declared as a friend, and when the name of the friend class or function is neither a qualified name nor a template-id, scopes outside the innermost enclosing namespace are not considered.
This is why ::h
is not considered: It is neither a qualified name nor a template-id. This is also why '::f2` is considered, because it is a template-id.
I think the inner declarations shadow the ones in the global namespace. Also, the friend declarations themselves are forward declarations, so they shadow the ones in the global namespace, and not just "refer" to those functions.
Referring to 3.3.10.1 "Name hiding" in N3485:
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).
11.3.4 Friends:
A function first declared in a friend declaration has external linkage (3.5). Otherwise, the function retains its previous linkage (7.1.1).
Looking at 3.5.2:
When a name has external linkage , the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With