150 lines
7.9 KiB
Markdown
150 lines
7.9 KiB
Markdown
[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)
|