7.9 KiB
[temp.friend]
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 task;template task* preempt(task*);
template class task {friend void next_time(); friend void process(task); friend task preempt(task*); template friend int func(C); friend class task; template friend class frd;};
Here, each specialization of thetask class template has the functionnext_time as a friend; becauseprocess does not have explicittemplate-arguments, each specialization of thetask class template has an appropriately typed functionprocess as a friend, and this friend is not a function template specialization; because the friendpreempt has an explicittemplate-argumentT, each specialization of thetask class template has the appropriate specialization of the function templatepreempt as a friend; and each specialization of thetask class template has all specializations of the function templatefunc as friends.
Similarly, each specialization of thetask class template has the class template specializationtask as a friend, and has all specializations of the class templatefrd 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 friend class B; // OKtemplate 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 friend struct A; class Y { };};
template struct A { X::Y ab; }; // OKtemplate 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 struct A {struct B { }; void f(); struct D {void g(); }; T h(); template T i();};template<> struct A {struct B { }; int f(); struct D {void g(); }; template int i();};template<> struct A<float*> {int *h();};
class C {template friend struct A::B; // grants friendship to A::B even though// it is not a specialization of A::Btemplate friend void A::f(); // does not grant friendship to A::f()// because its return type does not matchtemplate friend void A::D::g(); // error: A::D does not end with a simple-template-idtemplate friend int A<T>::h(); // grants friendship to A<int*>::h() and A<float*>::h()template template // grants friendship to instantiations of A::i() andfriend T A::i(); // to A::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 A { };class X {template 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.