它是 C++ gcc HEAD 10.0.0 20190 相对于友元函数的错误吗

Is it a bug of C++ gcc HEAD 10.0.0 20190 relative to friend functions

以下程序使用clang HEAD 10.0.0

编译
#include <iostream>

template <class T>
void f( const T & );

class A
{
public:
    A( int x = 0 ) : x( x ) {}

    friend void ::f( const A & );
private:
    int x;
};

template <class T>
void f( const T &t )
{
    std::cout << "t.x = " << t.x << '\n';
}


int main()
{
    A a( 10 );
    f( a );
}

程序输出为

t.x = 10

但是当使用gcc HEAD 10.0.0 20190编译器时会输出错误

prog.cc:11:32: error: 'void f(const A&)' should have been declared inside '::'
   11 |     friend void ::f( const A & );
      |                                ^ 

是编译器的问题还是我做错了什么?

归档91618.


[temp.friend]/1 读作:

A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or a non-template function or class. For a friend function declaration that is not a template declaration:

  • if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise,
  • if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, the friend declaration refers to that function, otherwise,
  • 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 ([temp.deduct.decl]), otherwise,
  • the name shall be an unqualified-id that declares (or redeclares) a non-template function.

第三个项目符号应该允许:

template <class T> void f(T);

struct A {
    friend void ::f(A);
};

::f 是一个 qualified-id 并且找到了一个匹配的函数模板,所以它应该可以工作。但是 gcc 要求我们写 ::f<>,这是一个 template-id,以坚持第一个项目符号。