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

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

本文关键字:函数 错误 好友 20190 gcc C++ HEAD 相对于      更新时间:2023-10-16

以下程序使用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 内容如下:

类或类模板的友元可以是函数模板或类模板、函数模板或类模板

的专用化,也可以是非模板函数或类。对于不是模板声明的友元函数声明:

  • 如果 friend 的名称是限定或非限定模板 ID,则 friend 声明是指函数模板的专用化,否则,
  • 如果 friend 的名称是限定 ID,并且在指定的类或命名空间中找到匹配的非模板函数,则 friend 声明引用该函数,否则,
  • 如果 friend 的名称是限定 ID,并且在指定的类或命名空间中找到匹配的函数模板,则 friend 声明引用该函数模板的推导专用化 ([temp.deduct.decl](,否则,
  • 该名称应为声明(或重新声明(非模板函数的非限定 ID

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

template <class T> void f(T);
struct A {
friend void ::f(A);
};

::f是一个限定 id,并且找到了匹配的函数模板,因此它应该可以工作。但是 gcc 要求我们写::f<>,这是一个模板 ID,以遵守第一个项目符号。