Description
Full name of submitter (unless configured in github; will be published with the issue): Jim X
Consider this example:
template<int N>
struct A{
friend void fun(A){}
};
int main(){
fun(A<0>{});
}
[temp.friend] p2 says:
Friend classes, class templates, functions, or function templates can be declared within a class template.
When a template is instantiated, its friend declarations are found by name lookup as if the specialization had been explicitly declared at its point of instantiation.
[temp.fct.general] p2 says:
A non-template function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.
The friend declaration defined in the template class A is not a function template, so the instantiated one, in terms of the wording, is not considered a specialization. [temp.spec.general] p4 says:
A specialization is a class, variable, function, or class member that is either instantiated ([temp.inst]) from a templated entity or is an explicit specialization ([temp.expl.spec]) of a templated entity.
However, [temp.spec.general] P2 does not discuss the friend function for that class template. It only says that:
A member function, a member class, a member enumeration, or a static data member of a class template instantiated from the member definition of the class template is called, respectively, an instantiated member function, member class, member enumeration, or static data member.
However, a friend function is not a member of the enclosing class/class template.
Suggested Resolution
[temp.spec.general] P2:
A friend function or class instantiated from the declaration declared in the class template is called, respectively, an instantiated friend function or class.
Change [temp.fct.general] p2
A non-template function is not related to a templated function