使用函数定义作为朋友声明时,clang和gcc的行为有所不同

问题描述

当使用编译选项“ -std = c ++ 17 -pedantic-errors”编译以下代码时,编译会产生gcc错误,而clang没有错误(请参见下面的编译器资源管理器链接)。这怎么可能?这是未定义的行为,还是其中一个编译器存在错误?请注意,我正在编译“ -pedantic-errors”,因此区别不应该是由于编译器扩展引起的。

template<typename T>
void f()
{
}

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

int main()
{
}

Run on 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()
      |      ^

解决方法

[dcl。意义] / 1应该禁止

声明者ID 中出现的 unqualified-id 应该是简单的 identifier ,除了[…]和模板声明专业化或部分专业化([temp.spec])。

有人可能会说这实际上是“模板专业化”的声明,并且交叉引用不足以将声明的形式限制为该条款中所述的一种。 。但是,鉴于在类外(甚至是Clang)都不允许此类声明,因此将其称为 bug