繁体   English   中英

合格的友元函数模板实例化

[英]Qualified friend function template instantiation

查看C++ 模板:完整指南(第 2 版) /今天早上的官方网站我遇到了一个我不太明白的部分(如果你有这本书,则为 12.5.2)。 省略这里似乎无关的内容:

如果名称 [在朋友声明中] 后面没有尖括号,则有两种可能性

  1. 如果名称不合格 [...]

  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);
              ^~~~~~~~

我正在尝试深入了解这一点,并且我已经重新输入了几次代码(尽管如果有人拥有这本书,则再次输入......)。 规则是否正确而编译器是错误的? 代码不是规则的正确示范吗?

完整的代码包括一个较早的朋友函数定义:

class Comrades {
    friend void multiply(int) { }
    friend void ::multiply(int);
}

哪个 clang 接受而 gcc 拒绝(这是一个不同的问题)。 在任何一种情况下,它都没有证明作者声明的规则,它是第二个引用同一类中较早一个的规则。

书是对的。 [temp.friend]p1 - 突出显示相关部分:

对于不是模板声明的友元函数声明:

  • 如果朋友的名字是合格或不合格的模板ID ,[...]

  • 如果朋友的名字是一个合格的 id并且在指定的类或命名空间中找到匹配的非模板函数,[...]

  • 如果友元的名称是限定 ID并且在指定的类或命名空间中找到匹配的函数模板,则友元声明引用该函数模板的推导特化

  • [...]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM