[temp.friend] # 13 Templates [[temp]](./#temp) ## 13.7 Template declarations [[temp.decls]](temp.decls#temp.friend) ### 13.7.5 Friends [temp.friend] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3457) 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[.](#1.sentence-1) [*Example [1](#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 explicit[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*, 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 explicit[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")T, 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[.](#1.sentence-2) 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[.](#1.sentence-3) — *end example*] [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3519) Friend classes, class templates, functions, or function templates can be declared within a class template[.](#2.sentence-1) 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[.](#2.sentence-2) [*Note [1](#note-1)*: They can introduce entities that belong to an enclosing namespace scope ([[dcl.meaning]](dcl.meaning "9.3.4 Meaning of declarators")), in which case they are attached to the same module as the class template ([[module.unit]](module.unit "10.1 Module units and purviews"))[.](#2.sentence-3) — *end note*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3533) A friend template may be declared within a class or class template[.](#3.sentence-1) 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[.](#3.sentence-2) In these cases, all specializations of the friend class or friend function template are friends of the class or class template granting friendship[.](#3.sentence-3) [*Example [2](#example-2)*: class A {template friend class B; // OKtemplate friend void f(T) { /* ... */ } // OK}; — *end example*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3549) A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated ([[temp.inst]](temp.inst "13.9.2 Implicit instantiation")), partially specialized ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization")) or explicitly specialized ([[temp.expl.spec]](temp.expl.spec "13.9.4 Explicit specialization")), are friends of the class containing the template friend declaration[.](#4.sentence-1) [*Example [3](#example-3)*: class X {template friend struct A; class Y { };}; template struct A { X::Y ab; }; // OKtemplate struct A { X::Y ab; }; // OK — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3566) A template friend declaration may declare a member of a dependent type to be a friend[.](#5.sentence-1) The friend declaration shall declare a function or specify a type with an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"), in either case with a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ending with a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]"), *C*, whose [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") names a class template[.](#5.sentence-2) The template parameters of the template friend declaration shall be deducible from *C* ([[temp.deduct.type]](temp.deduct.type "13.10.3.6 Deducing template arguments from a type"))[.](#5.sentence-3) 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[.](#5.sentence-4) [*Example [4](#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 {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-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")template friend int *A::h(); // grants friendship to A​::​h() and A​::​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*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3620) A friend template shall not be declared in a local class[.](#6.sentence-1) [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3623) Friend declarations shall not declare partial specializations[.](#7.sentence-1) [*Example [5](#example-5)*: template class A { };class X {template friend class A; // error}; — *end example*] [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3634) 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[.](#8.sentence-1) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3641) A non-template friend declaration with a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") shall be a definition[.](#9.sentence-1) A friend function template with a constraint that depends on a template parameter from an enclosing template shall be a definition[.](#9.sentence-2) 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[.](#9.sentence-3)