c++ - 使用函数定义作为友元声明时,clang 和 gcc 之间的行为差异
问题描述
使用编译选项“-std=c++17 -pedantic-errors”编译以下代码时,编译会在 gcc 中出现错误,但在 clang 中没有错误(请参阅下面的编译器资源管理器链接)。这怎么可能?这是未定义的行为还是其中一个编译器有错误?请注意,我正在使用“-pedantic-errors”进行编译,因此差异不应该是因为编译器扩展。
template<typename T>
void f()
{
}
class C
{
friend void f<int>()
{
}
};
int main()
{
}
这是 gcc 生成的编译:
<source>:8:17: error: defining explicit specialization 'f<int>' in friend declaration
8 | friend void f<int>()
| ^~~~~~
<source>:8:17: error: ambiguating new declaration of 'void f()'
<source>:2:6: note: old declaration 'void f() [with T = int]'
2 | void f()
| ^
解决方案
[dcl.meaning]/1 应该禁止这样做:
declarator- id中出现的unqualified- id应该是一个简单的标识符,除了 […] 和模板特化或部分特化 ([temp.spec]) 的声明。
有人可能会争辩说,这实际上是“模板专业化”的声明,并且交叉引用不足以将声明的形式限制为该子条款中描述的形式之一。但是,鉴于在类之外(即使是 Clang)不允许这样的声明,将其称为bug更为合理。
推荐阅读
- reactjs - React admin:我可以使用一个表单创建两个资源吗?
- python - 我不知道如何在第二次运行程序时将列表设置为移动到下一个元素
- sql - 填写表格中缺少的余额和日期以跟踪余额
- javascript - 如何在单击另一个切换按钮时禁用引导切换按钮?
- python - 在 anaconda 中使用 keras 激活 tensorflow 环境时出现以下问题
- html - 如何在 HTML 和 CSS 中创建水平列?
- tensorflow - N 个时间序列馈送到具有 N 个 lstm 单元的一层,如何将 lstm 水平连接为一个层?
- java - 将 ArrayAdapter 发送到另一个活动的代码?
- scala - SPARK SQL:orderBy 之后的 groupBy 是否保持该顺序?
- javascript - 如何将建议的结果放在首位