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

7.9 KiB
Raw Permalink Blame History

[temp.friend]

13 Templates [temp]

13.7 Template declarations [temp.decls]

13.7.5 Friends [temp.friend]

1

#

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.

[Example 1: template class task;template task* preempt(task*);

template class task {friend void next_time(); friend void process(task); friend task preempt(task*); template friend int func(C); friend class task; template friend class frd;};

Here, each specialization of thetask class template has the functionnext_time as a friend; becauseprocess does not have explicittemplate-arguments, 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 explicittemplate-argumentT, 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.

Similarly, each specialization of thetask class template has the class template specializationtask as a friend, and has all specializations of the class templatefrd as friends.

— end example]

2

#

Friend classes, class templates, functions, or function templates can be declared within a class template.

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.

[Note 1:

They can introduce entities that belong to an enclosing namespace scope ([dcl.meaning]), in which case they are attached to the same module as the class template ([module.unit]).

— end note]

3

#

A friend template may be declared within a class or class template.

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.

In these cases, all specializations of the friend class or friend function template are friends of the class or class template granting friendship.

[Example 2: class A {template friend class B; // OKtemplate friend void f(T) { /* ... */ } // OK}; — end example]

4

#

A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated ([temp.inst]), partially specialized ([temp.spec.partial]) or explicitly specialized ([temp.expl.spec]), are friends of the class containing the template friend declaration.

[Example 3: class X {template friend struct A; class Y { };};

template struct A { X::Y ab; }; // OKtemplate struct A<T*> { X::Y ab; }; // OK — end example]

5

#

A template friend declaration may declare a member of a dependent type to be a friend.

The friend declaration shall declare a function or specify a type with an elaborated-type-specifier, in either case with a nested-name-specifier ending with a simple-template-id, C, whose template-name names a class template.

The template parameters of the template friend declaration shall be deducible from C ([temp.deduct.type]).

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.

[Example 4: template struct A {struct B { }; void f(); struct D {void g(); }; T h(); template T i();};template<> struct A {struct B { }; int f(); struct D {void g(); }; template int i();};template<> struct A<float*> {int *h();};

class C {template friend struct A::B; // grants friendship to A::B even though// it is not a specialization of A::Btemplate friend void A::f(); // does not grant friendship to A::f()// because its return type does not matchtemplate friend void A::D::g(); // error: A::D does not end with a simple-template-idtemplate friend int A<T>::h(); // grants friendship to A<int*>::h() and A<float*>::h()template template // grants friendship to instantiations of A::i() andfriend T A::i(); // to A::i(), and thereby to all specializations}; // of those function templates — end example]

6

#

A friend template shall not be declared in a local class.

7

#

Friend declarations shall not declare partial specializations.

[Example 5: template class A { };class X {template friend class A<T*>; // error}; — end example]

8

#

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.

9

#

A non-template friend declaration with a requires-clause shall be a definition.

A friend function template with a constraint that depends on a template parameter from an enclosing template shall be a definition.

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.