From Jason Turner

[temp.friend]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpqm7neyz2/{from.md → to.md} +37 -18
tmp/tmpqm7neyz2/{from.md → to.md} RENAMED
@@ -12,11 +12,11 @@ declaration that is not a template declaration:
12
  non-template function is found in the specified class or namespace,
13
  the friend declaration refers to that function, otherwise,
14
  - if the name of the friend is a *qualified-id* and a matching function
15
  template is found in the specified class or namespace, the friend
16
  declaration refers to the deduced specialization of that function
17
- template ([[temp.deduct.decl]]), otherwise,
18
  - the name shall be an *unqualified-id* that declares (or redeclares) a
19
  non-template function.
20
 
21
  [*Example 1*:
22
 
@@ -67,13 +67,13 @@ class A {
67
  ```
68
 
69
  — *end example*]
70
 
71
  A template friend declaration specifies that all specializations of that
72
- template, whether they are implicitly instantiated ([[temp.inst]]),
73
- partially specialized ([[temp.class.spec]]) or explicitly specialized (
74
- [[temp.expl.spec]]), are friends of the class containing the template
75
  friend declaration.
76
 
77
  [*Example 3*:
78
 
79
  ``` cpp
@@ -86,52 +86,63 @@ template<class T> struct A { X::Y ab; }; // OK
86
  template<class T> struct A<T*> { X::Y ab; }; // OK
87
  ```
88
 
89
  — *end example*]
90
 
91
- A member of a class template may be declared to be a friend of a
92
- non-template class. In this case, the corresponding member of every
93
- specialization of the primary class template and class template partial
94
- specializations thereof is a friend of the class granting friendship.
95
- For explicit specializations and specializations of partial
96
- specializations, the corresponding member is the member (if any) that
97
- has the same name, kind (type, function, class template, or function
98
- template), template parameters, and signature as the member of the class
99
- template instantiation that would otherwise have been generated.
 
 
 
100
 
101
  [*Example 4*:
102
 
103
  ``` cpp
104
  template<class T> struct A {
105
  struct B { };
106
  void f();
107
  struct D {
108
  void g();
109
  };
 
 
110
  };
111
  template<> struct A<int> {
112
  struct B { };
113
  int f();
114
  struct D {
115
  void g();
116
  };
 
 
 
 
117
  };
118
 
119
  class C {
120
  template<class T> friend struct A<T>::B; // grants friendship to A<int>::B even though
121
  // it is not a specialization of A<T>::B
122
  template<class T> friend void A<T>::f(); // does not grant friendship to A<int>::f()
123
  // because its return type does not match
124
- template<class T> friend void A<T>::D::g(); // does not grant friendship to A<int>::D::g()
125
- // because A<int>::D is not a specialization of A<T>::D
126
- };
 
 
127
  ```
128
 
129
  — *end example*]
130
 
131
  [*Note 1*: A friend declaration may first declare a member of an
132
- enclosing namespace scope ([[temp.inject]]). — *end note*]
133
 
134
  A friend template shall not be declared in a local class.
135
 
136
  Friend declarations shall not declare partial specializations.
137
 
@@ -146,7 +157,15 @@ class X {
146
 
147
  — *end example*]
148
 
149
  When a friend declaration refers to a specialization of a function
150
  template, the function parameter declarations shall not include default
151
- arguments, nor shall the inline specifier be used in such a declaration.
 
 
 
 
 
 
 
 
152
 
 
12
  non-template function is found in the specified class or namespace,
13
  the friend declaration refers to that function, otherwise,
14
  - if the name of the friend is a *qualified-id* and a matching function
15
  template is found in the specified class or namespace, the friend
16
  declaration refers to the deduced specialization of that function
17
+ template [[temp.deduct.decl]], otherwise,
18
  - the name shall be an *unqualified-id* that declares (or redeclares) a
19
  non-template function.
20
 
21
  [*Example 1*:
22
 
 
67
  ```
68
 
69
  — *end example*]
70
 
71
  A template friend declaration specifies that all specializations of that
72
+ template, whether they are implicitly instantiated [[temp.inst]],
73
+ partially specialized [[temp.class.spec]] or explicitly specialized
74
+ [[temp.expl.spec]], are friends of the class containing the template
75
  friend declaration.
76
 
77
  [*Example 3*:
78
 
79
  ``` cpp
 
86
  template<class T> struct A<T*> { X::Y ab; }; // OK
87
  ```
88
 
89
  — *end example*]
90
 
91
+ A template friend declaration may declare a member of a dependent type
92
+ to be a friend. The friend declaration shall declare a function or
93
+ specify a type with an *elaborated-type-specifier*, in either case with
94
+ a *nested-name-specifier* ending with a *simple-template-id*, *C*, whose
95
+ *template-name* names a class template. The template parameters of the
96
+ template friend declaration shall be deducible from *C* (
97
+ [[temp.deduct.type]]). In this case, a member of a specialization *S* of
98
+ the class template is a friend of the class granting friendship if
99
+ deduction of the template parameters of *C* from *S* succeeds, and
100
+ substituting the deduced template arguments into the friend declaration
101
+ produces a declaration that would be a valid redeclaration of the member
102
+ of the specialization.
103
 
104
  [*Example 4*:
105
 
106
  ``` cpp
107
  template<class T> struct A {
108
  struct B { };
109
  void f();
110
  struct D {
111
  void g();
112
  };
113
+ T h();
114
+ template<T U> T i();
115
  };
116
  template<> struct A<int> {
117
  struct B { };
118
  int f();
119
  struct D {
120
  void g();
121
  };
122
+ template<int U> int i();
123
+ };
124
+ template<> struct A<float*> {
125
+ int *h();
126
  };
127
 
128
  class C {
129
  template<class T> friend struct A<T>::B; // grants friendship to A<int>::B even though
130
  // it is not a specialization of A<T>::B
131
  template<class T> friend void A<T>::f(); // does not grant friendship to A<int>::f()
132
  // because its return type does not match
133
+ template<class T> friend void A<T>::D::g(); // error: A<T>::D does not end with a simple-template-id
134
+ template<class T> friend int *A<T*>::h(); // grants friendship to A<int*>::h() and A<float*>::h()
135
+ template<class T> template<T U> // grants friendship to instantiations of A<T>::i() and
136
+ friend T A<T>::i(); // to A<int>::i(), and thereby to all specializations
137
+ }; // of those function templates
138
  ```
139
 
140
  — *end example*]
141
 
142
  [*Note 1*: A friend declaration may first declare a member of an
143
+ enclosing namespace scope [[temp.inject]]. — *end note*]
144
 
145
  A friend template shall not be declared in a local class.
146
 
147
  Friend declarations shall not declare partial specializations.
148
 
 
157
 
158
  — *end example*]
159
 
160
  When a friend declaration refers to a specialization of a function
161
  template, the function parameter declarations shall not include default
162
+ arguments, nor shall the `inline`, `constexpr`, or `consteval`
163
+ specifiers be used in such a declaration.
164
+
165
+ A non-template friend declaration with a *requires-clause* shall be a
166
+ definition. A friend function template with a constraint that depends on
167
+ a template parameter from an enclosing template shall be a definition.
168
+ Such a constrained friend function or function template declaration does
169
+ not declare the same function or function template as a declaration in
170
+ any other scope.
171