看着
C++ Templates: The Complete Guide (2nd Edition)
/
official site
(总体来说很好)今天早上我遇到了一个我无法理解的部分(12.5.2如果你有这本书的话)。省略这里看起来不相关的内容:
如果[在友元声明中]的名称后面没有尖括号,则有两种可能
-
如果名称不合格[…]
-
如果名字
是
合格(包含
::
)名称必须引用以前声明的函数或函数模板。匹配函数优先于匹配函数模板。但是,这样的友元声明不能是定义。
使用以下代码
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
)无论哪种情况,它都不能证明作者所说的规则,而是引用同一类中较早的规则的第二个规则。