Files
2025-10-25 03:02:53 +03:00

150 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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)