From Jason Turner

[over.match.class.deduct]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp0_vsdl4a/{from.md → to.md} +237 -19
tmp/tmp0_vsdl4a/{from.md → to.md} RENAMED
@@ -1,43 +1,147 @@
1
  #### Class template argument deduction <a id="over.match.class.deduct">[[over.match.class.deduct]]</a>
2
 
3
- A set of functions and function templates is formed comprising:
 
 
 
4
 
5
- - For each constructor of the primary class template designated by the
6
- *template-name*, if the template is defined, a function template with
7
- the following properties:
8
- - The template parameters are the template parameters of the class
9
- template followed by the template parameters (including default
10
- template arguments) of the constructor, if any.
11
  - The types of the function parameters are those of the constructor.
12
  - The return type is the class template specialization designated by
13
- the *template-name* and template arguments corresponding to the
14
- template parameters obtained from the class template.
15
- - If the primary class template `C` is not defined or does not declare
16
- any constructors, an additional function template derived as above
17
- from a hypothetical constructor `C()`.
18
  - An additional function template derived as above from a hypothetical
19
  constructor `C(C)`, called the *copy deduction candidate*.
20
  - For each *deduction-guide*, a function or function template with the
21
  following properties:
22
  - The template parameters, if any, and function parameters are those
23
  of the *deduction-guide*.
24
  - The return type is the *simple-template-id* of the
25
  *deduction-guide*.
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  Initialization and overload resolution are performed as described in
28
  [[dcl.init]] and [[over.match.ctor]], [[over.match.copy]], or
29
  [[over.match.list]] (as appropriate for the type of initialization
30
- performed) for an object of a hypothetical class type, where the
31
- selected functions and function templates are considered to be the
32
  constructors of that class type for the purpose of forming an overload
33
  set, and the initializer is provided by the context in which class
34
- template argument deduction was performed. Each such notional
35
- constructor is considered to be explicit if the function or function
36
- template was generated from a constructor or *deduction-guide* that was
37
- declared `explicit`. All such notional constructors are considered to be
38
- public members of the hypothetical class type.
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  [*Example 1*:
41
 
42
  ``` cpp
43
  template <class T> struct A {
@@ -65,9 +169,123 @@ template <class T> struct B {
65
  template <class U> using TA = T;
66
  template <class U> B(U, TA<U>);
67
  };
68
 
69
  B b{(int*)0, (char*)0}; // OK, deduces B<char*>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  ```
71
 
72
  — *end example*]
73
 
 
1
  #### Class template argument deduction <a id="over.match.class.deduct">[[over.match.class.deduct]]</a>
2
 
3
+ When resolving a placeholder for a deduced class type
4
+ [[dcl.type.class.deduct]] where the *template-name* names a primary
5
+ class template `C`, a set of functions and function templates, called
6
+ the guides of `C`, is formed comprising:
7
 
8
+ - If `C` is defined, for each constructor of `C`, a function template
9
+ with the following properties:
10
+ - The template parameters are the template parameters of `C` followed
11
+ by the template parameters (including default template arguments) of
12
+ the constructor, if any.
 
13
  - The types of the function parameters are those of the constructor.
14
  - The return type is the class template specialization designated by
15
+ `C` and template arguments corresponding to the template parameters
16
+ of `C`.
17
+ - If `C` is not defined or does not declare any constructors, an
18
+ additional function template derived as above from a hypothetical
19
+ constructor `C()`.
20
  - An additional function template derived as above from a hypothetical
21
  constructor `C(C)`, called the *copy deduction candidate*.
22
  - For each *deduction-guide*, a function or function template with the
23
  following properties:
24
  - The template parameters, if any, and function parameters are those
25
  of the *deduction-guide*.
26
  - The return type is the *simple-template-id* of the
27
  *deduction-guide*.
28
 
29
+ In addition, if `C` is defined and its definition satisfies the
30
+ conditions for an aggregate class [[dcl.init.aggr]] with the assumption
31
+ that any dependent base class has no virtual functions and no virtual
32
+ base classes, and the initializer is a non-empty *braced-init-list* or
33
+ parenthesized *expression-list*, and there are no *deduction-guide*s for
34
+ `C`, the set contains an additional function template, called the
35
+ *aggregate deduction candidate*, defined as follows. Let x₁, …, xₙ be
36
+ the elements of the *initializer-list* or *designated-initializer-list*
37
+ of the *braced-init-list*, or of the *expression-list*. For each xᵢ, let
38
+ eᵢ be the corresponding aggregate element of `C` or of one of its
39
+ (possibly recursive) subaggregates that would be initialized by xᵢ
40
+ [[dcl.init.aggr]] if
41
+
42
+ - brace elision is not considered for any aggregate element that has a
43
+ dependent non-array type or an array type with a value-dependent
44
+ bound, and
45
+ - each non-trailing aggregate element that is a pack expansion is
46
+ assumed to correspond to no elements of the initializer list, and
47
+ - a trailing aggregate element that is a pack expansion is assumed to
48
+ correspond to all remaining elements of the initializer list (if any).
49
+
50
+ If there is no such aggregate element eᵢ for any xᵢ, the aggregate
51
+ deduction candidate is not added to the set. The aggregate deduction
52
+ candidate is derived as above from a hypothetical constructor
53
+ `C`(`T₁`, …, `Tₙ`), where
54
+
55
+ - if eᵢ is of array type and xᵢ is a *braced-init-list* or
56
+ *string-literal*, `Tᵢ` is an rvalue reference to the declared type of
57
+ eᵢ, and
58
+ - otherwise, `Tᵢ` is the declared type of eᵢ,
59
+
60
+ except that additional parameter packs of the form `Pⱼ` `...` are
61
+ inserted into the parameter list in their original aggregate element
62
+ position corresponding to each non-trailing aggregate element of type
63
+ `Pⱼ` that was skipped because it was a parameter pack, and the trailing
64
+ sequence of parameters corresponding to a trailing aggregate element
65
+ that is a pack expansion (if any) is replaced by a single parameter of
66
+ the form `Tₙ` `...`.
67
+
68
+ When resolving a placeholder for a deduced class type
69
+ [[dcl.type.simple]] where the *template-name* names an alias template
70
+ `A`, the *defining-type-id* of `A` must be of the form
71
+
72
+ ``` bnf
73
+ typenameₒₚₜ nested-name-specifierₒₚₜ templateₒₚₜ simple-template-id
74
+ ```
75
+
76
+ as specified in [[dcl.type.simple]]. The guides of `A` are the set of
77
+ functions or function templates formed as follows. For each function or
78
+ function template `f` in the guides of the template named by the
79
+ *simple-template-id* of the *defining-type-id*, the template arguments
80
+ of the return type of `f` are deduced from the *defining-type-id* of `A`
81
+ according to the process in [[temp.deduct.type]] with the exception that
82
+ deduction does not fail if not all template arguments are deduced. Let
83
+ `g` denote the result of substituting these deductions into `f`. If
84
+ substitution succeeds, form a function or function template `f'` with
85
+ the following properties and add it to the set of guides of `A`:
86
+
87
+ - The function type of `f'` is the function type of `g`.
88
+ - If `f` is a function template, `f'` is a function template whose
89
+ template parameter list consists of all the template parameters of `A`
90
+ (including their default template arguments) that appear in the above
91
+ deductions or (recursively) in their default template arguments,
92
+ followed by the template parameters of `f` that were not deduced
93
+ (including their default template arguments), otherwise `f'` is not a
94
+ function template.
95
+ - The associated constraints [[temp.constr.decl]] are the conjunction of
96
+ the associated constraints of `g` and a constraint that is satisfied
97
+ if and only if the arguments of `A` are deducible (see below) from the
98
+ return type.
99
+ - If `f` is a copy deduction candidate [[over.match.class.deduct]], then
100
+ `f'` is considered to be so as well.
101
+ - If `f` was generated from a *deduction-guide*
102
+ [[over.match.class.deduct]], then `f'` is considered to be so as well.
103
+ - The *explicit-specifier* of `f'` is the *explicit-specifier* of `g`
104
+ (if any).
105
+
106
+ The arguments of a template `A` are said to be deducible from a type `T`
107
+ if, given a class template
108
+
109
+ ``` cpp
110
+ template <typename> class AA;
111
+ ```
112
+
113
+ with a single partial specialization whose template parameter list is
114
+ that of `A` and whose template argument list is a specialization of `A`
115
+ with the template argument list of `A` [[temp.dep.type]], `AA<T>`
116
+ matches the partial specialization.
117
+
118
  Initialization and overload resolution are performed as described in
119
  [[dcl.init]] and [[over.match.ctor]], [[over.match.copy]], or
120
  [[over.match.list]] (as appropriate for the type of initialization
121
+ performed) for an object of a hypothetical class type, where the guides
122
+ of the template named by the placeholder are considered to be the
123
  constructors of that class type for the purpose of forming an overload
124
  set, and the initializer is provided by the context in which class
125
+ template argument deduction was performed. The following exceptions
126
+ apply:
127
+
128
+ - The first phase in [[over.match.list]] (considering initializer-list
129
+ constructors) is omitted if the initializer list consists of a single
130
+ expression of type cv `U`, where `U` is, or is derived from, a
131
+ specialization of the class template directly or indirectly named by
132
+ the placeholder.
133
+ - During template argument deduction for the aggregate deduction
134
+ candidate, the number of elements in a trailing parameter pack is only
135
+ deduced from the number of remaining function arguments if it is not
136
+ otherwise deduced.
137
+
138
+ If the function or function template was generated from a constructor or
139
+ *deduction-guide* that had an *explicit-specifier*, each such notional
140
+ constructor is considered to have that same *explicit-specifier*. All
141
+ such notional constructors are considered to be public members of the
142
+ hypothetical class type.
143
 
144
  [*Example 1*:
145
 
146
  ``` cpp
147
  template <class T> struct A {
 
169
  template <class U> using TA = T;
170
  template <class U> B(U, TA<U>);
171
  };
172
 
173
  B b{(int*)0, (char*)0}; // OK, deduces B<char*>
174
+
175
+ template <typename T>
176
+ struct S {
177
+ T x;
178
+ T y;
179
+ };
180
+
181
+ template <typename T>
182
+ struct C {
183
+ S<T> s;
184
+ T t;
185
+ };
186
+
187
+ template <typename T>
188
+ struct D {
189
+ S<int> s;
190
+ T t;
191
+ };
192
+
193
+ C c1 = {1, 2}; // error: deduction failed
194
+ C c2 = {1, 2, 3}; // error: deduction failed
195
+ C c3 = {{1u, 2u}, 3}; // OK, deduces C<int>
196
+
197
+ D d1 = {1, 2}; // error: deduction failed
198
+ D d2 = {1, 2, 3}; // OK, braces elided, deduces D<int>
199
+
200
+ template <typename T>
201
+ struct E {
202
+ T t;
203
+ decltype(t) t2;
204
+ };
205
+
206
+ E e1 = {1, 2}; // OK, deduces E<int>
207
+
208
+ template <typename... T>
209
+ struct Types {};
210
+
211
+ template <typename... T>
212
+ struct F : Types<T...>, T... {};
213
+
214
+ struct X {};
215
+ struct Y {};
216
+ struct Z {};
217
+ struct W { operator Y(); };
218
+
219
+ F f1 = {Types<X, Y, Z>{}, {}, {}}; // OK, F<X, Y, Z> deduced
220
+ F f2 = {Types<X, Y, Z>{}, X{}, Y{}}; // OK, F<X, Y, Z> deduced
221
+ F f3 = {Types<X, Y, Z>{}, X{}, W{}}; // error: conflicting types deduced; operator Y not considered
222
+ ```
223
+
224
+ — *end example*]
225
+
226
+ [*Example 2*:
227
+
228
+ ``` cpp
229
+ template <class T, class U> struct C {
230
+ C(T, U); // #1
231
+ };
232
+ template<class T, class U>
233
+ C(T, U) -> C<T, std::type_identity_t<U>>; // #2
234
+
235
+ template<class V> using A = C<V *, V *>;
236
+ template<std::integral W> using B = A<W>;
237
+
238
+ int i{};
239
+ double d{};
240
+ A a1(&i, &i); // deduces A<int>
241
+ A a2(i, i); // error: cannot deduce V * from i
242
+ A a3(&i, &d); // error: #1: cannot deduce (V*, V*) from (int *, double *)
243
+ // #2: cannot deduce A<V> from C<int *, double *>
244
+ B b1(&i, &i); // deduces B<int>
245
+ B b2(&d, &d); // error: cannot deduce B<W> from C<double *, double *>
246
+ ```
247
+
248
+ Possible exposition-only implementation of the above procedure:
249
+
250
+ ``` cpp
251
+ // The following concept ensures a specialization of A is deduced.
252
+ template <class> class AA;
253
+ template <class V> class AA<A<V>> { };
254
+ template <class T> concept deduces_A = requires { sizeof(AA<T>); };
255
+
256
+ // f1 is formed from the constructor #1 of C, generating the following function template
257
+ template<T, U>
258
+ auto f1(T, U) -> C<T, U>;
259
+
260
+ // Deducing arguments for C<T, U> from C<V *, V*> deduces T as V * and U as V *;
261
+ // f1' is obtained by transforming f1 as described by the above procedure.
262
+ template<class V> requires deduces_A<C<V *, V *>>
263
+ auto f1_prime(V *, V*) -> C<V *, V *>;
264
+
265
+ // f2 is formed from the deduction-guide #2 of C
266
+ template<class T, class U> auto f2(T, U) -> C<T, std::type_identity_t<U>>;
267
+
268
+ // Deducing arguments for C<T, std::type_identity_t<U>> from C<V *, V*> deduces T as V *;
269
+ // f2' is obtained by transforming f2 as described by the above procedure.
270
+ template<class V, class U>
271
+ requires deduces_A<C<V *, std::type_identity_t<U>>>
272
+ auto f2_prime(V *, U) -> C<V *, std::type_identity_t<U>>;
273
+
274
+ // The following concept ensures a specialization of B is deduced.
275
+ template <class> class BB;
276
+ template <class V> class BB<B<V>> { };
277
+ template <class T> concept deduces_B = requires { sizeof(BB<T>); };
278
+
279
+ // The guides for B derived from the above f1' and f2' for A are as follows:
280
+ template<std::integral W>
281
+ requires deduces_A<C<W *, W *>> && deduces_B<C<W *, W *>>
282
+ auto f1_prime_for_B(W *, W *) -> C<W *, W *>;
283
+
284
+ template<std::integral W, class U>
285
+ requires deduces_A<C<W *, std::type_identity_t<U>>> &&
286
+ deduces_B<C<W *, std::type_identity_t<U>>>
287
+ auto f2_prime_for_B(W *, U) -> C<W *, std::type_identity_t<U>>;
288
  ```
289
 
290
  — *end example*]
291