13 Templates [temp]

13.7 Template declarations [temp.decls]

13.7.5 Friends [temp.friend]

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.
[Example 1: template<class T> class task; template<class T> task<T>* preempt(task<T>*); template<class T> class task { friend void next_time(); friend void process(task<T>*); friend task<T>* preempt<T>(task<T>*); template<class C> friend int func(C); friend class task<int>; template<class P> friend class frd; };
Here, each specialization of the task class template has the function next_time as a friend; because process does not have explicit template-arguments, each specialization of the task class template has an appropriately typed function process as a friend, and this friend is not a function template specialization; because the friend preempt has an explicit template-argument T, each specialization of the task class template has the appropriate specialization of the function template preempt as a friend; and each specialization of the task class template has all specializations of the function template func as friends.
Similarly, each specialization of the task class template has the class template specialization task<int> as a friend, and has all specializations of the class template frd as friends.
— end example]
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.
[Note 1: 
They can introduce entities that belong to an enclosing namespace scope ([dcl.meaning]), in which case they are attached to the same module as the class template ([module.unit]).
— end note]
A friend template may be declared within a class or class template.
A friend function template may be defined within a class or class template, but a friend class template may not be defined in a class or class template.
In these cases, all specializations of the friend class or friend function template are friends of the class or class template granting friendship.
[Example 2: class A { template<class T> friend class B; // OK template<class T> friend void f(T) { /* ... */ } // OK }; — end example]
A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated ([temp.inst]), partially specialized ([temp.spec.partial]) or explicitly specialized ([temp.expl.spec]), are friends of the class containing the template friend declaration.
[Example 3: class X { template<class T> friend struct A; class Y { }; }; template<class T> struct A { X::Y ab; }; // OK template<class T> struct A<T*> { X::Y ab; }; // OK — end example]
A template friend declaration may declare a member of a dependent type to be a friend.
The friend declaration shall declare a function or specify a type with an elaborated-type-specifier, in either case with a nested-name-specifier ending with a simple-template-id, C, whose template-name names a class template.
The template parameters of the template friend declaration shall be deducible from C ([temp.deduct.type]).
In this case, a member of a specialization S of the class template is a friend of the class granting friendship if deduction of the template parameters of C from S succeeds, and substituting the deduced template arguments into the friend declaration produces a declaration that corresponds to the member of the specialization.
[Example 4: template<class T> struct A { struct B { }; void f(); struct D { void g(); }; T h(); template<T U> T i(); }; template<> struct A<int> { struct B { }; int f(); struct D { void g(); }; template<int U> int i(); }; template<> struct A<float*> { int *h(); }; class C { template<class T> friend struct A<T>::B; // grants friendship to A<int>​::​B even though // it is not a specialization of A<T>​::​B template<class T> friend void A<T>::f(); // does not grant friendship to A<int>​::​f() // because its return type does not match template<class T> friend void A<T>::D::g(); // error: A<T>​::​D does not end with a simple-template-id template<class T> friend int *A<T*>::h(); // grants friendship to A<int*>​::​h() and A<float*>​::​h() template<class T> template<T U> // grants friendship to instantiations of A<T>​::​i() and friend T A<T>::i(); // to A<int>​::​i(), and thereby to all specializations }; // of those function templates — end example]
A friend template shall not be declared in a local class.
Friend declarations shall not declare partial specializations.
[Example 5: template<class T> class A { }; class X { template<class T> friend class A<T*>; // error }; — end example]
When a friend declaration refers to a specialization of a function template, the function parameter declarations shall not include default arguments, nor shall the inline, constexpr, or consteval specifiers be used in such a declaration.
A non-template friend declaration with a requires-clause shall be a definition.
A friend function template with a constraint that depends on a template parameter from an enclosing template shall be a definition.
Such a constrained friend function or function template declaration does not declare the same function or function template as a declaration in any other scope.