This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

149
cppdraft/temp/friend.md Normal file
View File

@@ -0,0 +1,149 @@
[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.3Names 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.3Names 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.4Meaning of declarators")),
in which case they are attached to
the same module as the class template ([[module.unit]](module.unit "10.1Module 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.2Implicit instantiation")), partially
specialized ([[temp.spec.partial]](temp.spec.partial "13.7.6Partial specialization")) or explicitly specialized ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit 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.5Elaborated type specifiers[dcl.type.elab]"),
in either case with a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ending with a [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]"), *C*,
whose [*template-name*](temp.names#nt:template-name "13.3Names 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.6Deducing 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.3Names 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.1Preamble[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)