C++ 是否可以调用注入的友元模板函数?

C++ 是否可以调用注入的友元模板函数?,c++,c++11,friend,function-templates,C++,C++11,Friend,Function Templates,为了与类中的其他(非模板)函数保持一致,我想定义并调用一个friend模板函数 我可以毫无问题地定义它(参见下面的函数t) 即使这是不可能的,我很惊讶我被允许定义它 我用gcc 8和clang 7对此进行了测试。要使其工作,您需要两个转发声明 以下两行代码应位于名称空间ns之前 struct S; //Needed because S is used as a parameter in the function template template<class T> void t(S

为了与类中的其他(非模板)函数保持一致,我想定义并调用一个friend模板函数

我可以毫无问题地定义它(参见下面的函数
t

即使这是不可能的,我很惊讶我被允许定义它


我用gcc 8和clang 7对此进行了测试。

要使其工作,您需要两个转发声明

以下两行代码应位于名称空间
ns
之前

struct S; //Needed because S is used as a parameter in the function template
template<class T> void t(S const&);

请参见演示。

可能重复的或更具体的我发现非常奇怪,您可以在名称空间之外声明
S
t
。这怎么可能?(在名称空间中执行此操作似乎是可能的,但却有所不同)。根据,这是可能的。“仅由类键标识符组成的声明;是当前作用域中名称的重新声明或标识符作为类名的转发声明。它将类名引入当前作用域。”。因此,您将不再获得错误:<代码>未在该作用域中声明< /C> >。我使用C++已经有一段时间了,我仍然觉得这很奇怪。
int main(){
    ns::S s;
    s.m();
    f(s);
//  t<int>(s); // error: ‘t’ was not declared in this scope (I was expecting this to work)
//  ns::t<int>(s); // error: ‘t’ is not a member of ‘ns’
//  ns::S::t<int>(s); // error: ‘t’ is not a member of ‘ns::S’
}
struct S; //Needed because S is used as a parameter in the function template
template<class T> void t(S const&);
t<int>(s);