Looking at C++ Templates: The Complete Guide (2nd Edition)/official site this morning I came across a section I can't quite make sense out of (12.5.2 if you have the book). Omitting what seems irrelevant here:
If the name [in the friend declaration] is not followed by angle brackets there are two possibilities
If the name isn't qualified [...]
If the name is qualified (it contains ::
), the name must refer to a previously declared function or function template. A matching function is preferred over a matching function template. However, such a friend declaration cannot be a definition.
With the following code
void multiply(void*);
template <typename T>
void multiply(T);
class Comrades {
// ... skipping some friends that do not effect the error message
friend void ::multiply(int); // refers to an instance of the template
// ...
};
gcc error:
error: ‘void multiply(int)’ should have been declared inside ‘::’
friend void ::multiply(int);
^
clang error:
error: out-of-line declaration of 'multiply' does not match any
declaration in the global namespace
friend void ::multiply(int);
^~~~~~~~
I'm trying to get to the bottom of this, and I've retyped the code a few times (though again if someone has the book...). Is the rule right and the compilers are wrong? Is the code not the right demonstration of the rule?
The complete code includes an earlier friend function definition:
class Comrades {
friend void multiply(int) { }
friend void ::multiply(int);
}
Which clang accepts and gcc rejects (that's a different question). In either case it doesn't demonstrate the rule that the author states, it's the second one referencing the earlier one in the same class.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…