c++ - 合格的 friend 功能模板实例化

标签 c++ templates language-lawyer c++17

今天早上看着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

  1. If the name isn't qualified [...]

  2. 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/

相关文章:

c++ - OSX clang++:用于cpp文件中显式实例化的模板的架构x86_64的 undefined symbol

C++11 引入了标准化的内存模型。这是什么意思?它将如何影响 C++ 编程?

c - 移动 unsigned int 超过它的大小,是否未定义?

c++ - 在 c/c++ 中包括结构和编译

c++ - QT如何将Qlist传递给类构造函数

c++ - 使用加法、减法和连接将数字组合成给定数字的方法

c++ - 如何有条件地为模板头设置编译器优化

具有派生类的 C++ 模板

c++ - 随机循环终止条件是否明确定义?

C++17 使用模板参数推导指南继承 lambda 集