C ++ Forward Declaration and Namespace Friendship

In accordance with 7.3.1.2 Definitions of namespace members in C ++ Standard ISO / IEC 14882: 2003 (E)

Each name that is first declared in a namespace is a member of this namespace. If a friend declaration in a non-local class first declares a class or function (this means that the class name or function is unqualified), the friend's class or function is a member of the innermost 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); first declared in the global namespace, it is a member of the global namespace. Why declaring a friend friend void h(int); in class Y considers A::h , not ::h ?

+6
source share
2 answers

The paragraph concludes with:

When searching for a previous declaration of a class or function declared as a friend, and when the friend's class or function name is neither a qualified name nor a template identifier, areas outside the innermost enclosing namespace are not considered.

This is why ::h not taken into account: this is not a qualified name, but a template identifier. This is also why ":: f2` is considered because it is the template identifier.

+2
source

I think that internal declarations obscure those contained in the global namespace. In addition, friend declarations themselves are forwarded declarations, so they obscure them in the global namespace, rather than simply โ€œreferencingโ€ these functions.

Referring to 3.3.10.1 "Hiding the Name" in N3485:

A name can be hidden by explicitly declaring the same name in a nested declarative region or derived class (10.2).

11.3.4 Friends:

A function declared in a friend declaration has an external binding (3.5). Otherwise, the function retains the previous relationship (7.1.1).

A look at 3.5.2:

If the name has an external connection, the object that it designates may be referred to by names from areas of other translation units or from other areas of the same translation unit.

+1
source

All Articles