今天早上看着C++ Templates: The Complete Guide (2nd Edition) / official site,我遇到了一个我不太明白的部分(如果您有这本书,则是12.5.2)。忽略这里无关紧要的内容:
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.
用下面的代码
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: ‘void multiply(int)’ should have been declared inside ‘::’
friend void ::multiply(int);
^
铛错误:
error: out-of-line declaration of 'multiply' does not match any
declaration in the global namespace
friend void ::multiply(int);
^~~~~~~~
我试图弄清这件事的深处,并且我已经重新输入了几次代码(不过如果有人拿着这本书的话……)。规则正确,编译器错误吗?代码不是规则的正确证明吗?
完整的代码包括一个较早的 friend 函数定义:
class Comrades {
friend void multiply(int) { }
friend void ::multiply(int);
}
哪个clang接受而gcc拒绝(这是different question)。无论哪种情况,它都没有证明作者陈述的规则,这是第二个引用同一类中较早版本的规则。
最佳答案
这本书是对的。 [temp.friend]p1-突出显示相关部分:
For a friend function declaration that is not a template declaration:
if the name of the friend is a qualified or unqualified template-id, [...]
if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, [...]
if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template
[...]
关于c++ - 合格的 friend 功能模板实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54055575/