nicebyte
nicebyte

Reputation: 1548

What are the rules for using qualified names in friend declarations?

The following code produces a compile error (on a recent version of gcc at least):

namespace a {

class X { friend void ::foo(); };

}

The error is:

'void foo()' should have been declared inside '::'

If we remove :: from the declaration, according to the standard, foo will be introduced into the namespace a (although it won't be visible). Predeclaring foo inside of a is not required.

My question is, given the above, why is predeclaring within the global namespace a requirement? Why doesn't the name foo become a member of the global namespace? I couldn't find any paragraph in the standard that would explicitly forbid that either, so I'm curious to know.

Upvotes: 2

Views: 123

Answers (1)

Wintermute
Wintermute

Reputation: 44043

The paragraph you're looking for is [dcl.meaning] (8.3 (1) in C++11):

(...) A declarator-id shall not be qualified except for the definition of a member function or static data member outside of its class, the definition or explicit instantiation of a function or variable of a namespace outside of its namespace, or the definition of an explicit specialization outside of its namespace, or the declaration of a friend function that is a member of another class or namespace. When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers (or, in the case of a namespace, of an element of the inline namespace set of that namespace).

(emphasis mine) What this means is that you cannot write

namespace a { }

void a::foo() { }

unless a::foo is already declared with an unqualified declarator inside the namespace. And since there is no exception for friends, you cannot do this for friends either.

A footnote in [namespace.memdef] (7.3.1.2 (3) in C++11) mentions this even more explicitly for the special case of friends:

(...) If a friend declaration in a non-local class first declares a class or function95 the friend class or function is a member of the innermost enclosing namespace. (...)

95) This implies that the name of the class or function is unqualified.

Upvotes: 2

Related Questions