Search code examples
c++namespacesfriendaccess-controlforward-declaration

C++ Forward Declaration and Friendship in Namespace


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?


Solution

  • 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.