首页 > 解决方案 > 使用函数定义作为友元声明时,clang 和 gcc 之间的行为差​​异

问题描述

使用编译选项“-std=c++17 -pedantic-errors”编译以下代码时,编译会在 gcc 中出现错误,但在 clang 中没有错误(请参阅下面的编译器资源管理器链接)。这怎么可能?这是未定义的行为还是其中一个编译器有错误?请注意,我正在使用“-pedantic-errors”进行编译,因此差异不应该是因为编译器扩展。

template<typename T>
void f()
{
}

class C
{
    friend void f<int>()
    {
    }
};

int main()
{
}

在 https://godbolt.org 上运行

这是 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()
      |      ^

标签: c++gccclanglanguage-lawyer

解决方案


[dcl.meaning]/1 应该禁止这样做:

declarator- id中出现的unqualified- id应该是一个简单的标识符,除了 […] 和模板特化或部分特化 ([temp.spec]) 的声明。

有人可能会争辩说,这实际上是“模板专业化”的声明,并且交叉引用不足以将声明的形式限制为该子条款中描述的形式之一。但是,鉴于在类之外(即使是 Clang)不允许这样的声明,将其称为bug更为合理。


推荐阅读