Init
This commit is contained in:
149
cppdraft/temp/friend.md
Normal file
149
cppdraft/temp/friend.md
Normal 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.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)
|
||||
Reference in New Issue
Block a user