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.