以下程序使用 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,以便遵守第一个项目符号。