[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 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 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<int> 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<class T> friend class B; // OKtemplate<class T> 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<class T> friend struct A; class Y { };};

template<class T> struct A { X::Y ab; }; // OKtemplate<class T> struct A<T*> { 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<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>​::​Btemplate<class T> friend void A<T>::f(); // does not grant friendship to A<int>​::​f()// because its return type does not matchtemplate<class T> friend void A<T>::D::g(); // error: A<T>​::​D does not end with a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")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() andfriend T A<T>::i(); // to A<int>​::​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 T> class A { };class X {template<class T> friend class A<T*>; // 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)
