From Jason Turner

[over.match.class.deduct]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpudd_ri55/{from.md → to.md} +97 -18
tmp/tmpudd_ri55/{from.md → to.md} RENAMED
@@ -37,35 +37,112 @@ 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
 
@@ -77,14 +154,16 @@ 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
@@ -94,14 +173,14 @@ the following properties and add it to the set of guides of `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
@@ -139,11 +218,11 @@ 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 {
148
  explicit A(const T&, ...) noexcept; // #1
149
  A(T&&, ...); // #2
@@ -221,11 +300,11 @@ 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
  };
@@ -252,11 +331,11 @@ Possible exposition-only implementation of the above procedure:
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 *>>
 
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
43
+ - a dependent non-array type,
44
+ - an array type with a value-dependent bound, or
45
+ - an array type with a dependent array element type and xᵢ is a string
46
+ literal; and
47
  - each non-trailing aggregate element that is a pack expansion is
48
  assumed to correspond to no elements of the initializer list, and
49
  - a trailing aggregate element that is a pack expansion is assumed to
50
  correspond to all remaining elements of the initializer list (if any).
51
 
52
  If there is no such aggregate element eᵢ for any xᵢ, the aggregate
53
  deduction candidate is not added to the set. The aggregate deduction
54
  candidate is derived as above from a hypothetical constructor
55
  `C`(`T₁`, …, `Tₙ`), where
56
 
57
+ - if eᵢ is of array type and xᵢ is a *braced-init-list*, `Tᵢ` is an
58
+ rvalue reference to the declared type of eᵢ, and
59
+ - if eᵢ is of array type and xᵢ is a *string-literal*, `Tᵢ` is an lvalue
60
+ reference to the const-qualified declared type of eᵢ, and
61
  - otherwise, `Tᵢ` is the declared type of eᵢ,
62
 
63
  except that additional parameter packs of the form `Pⱼ` `...` are
64
  inserted into the parameter list in their original aggregate element
65
  position corresponding to each non-trailing aggregate element of type
66
  `Pⱼ` that was skipped because it was a parameter pack, and the trailing
67
  sequence of parameters corresponding to a trailing aggregate element
68
  that is a pack expansion (if any) is replaced by a single parameter of
69
+ the form `Tₙ` `...`. In addition, if `C` is defined and inherits
70
+ constructors [[namespace.udecl]] from a direct base class denoted in the
71
+ *base-specifier-list* by a *class-or-decltype* `B`, let `A` be an alias
72
+ template whose template parameter list is that of `C` and whose
73
+ *defining-type-id* is `B`. If `A` is a deducible template
74
+ [[dcl.type.simple]], the set contains the guides of `A` with the return
75
+ type `R` of each guide replaced with `typename CC<R>::type` given a
76
+ class template
77
+
78
+ ``` cpp
79
+ template <typename> class CC;
80
+ ```
81
+
82
+ whose primary template is not defined and with a single partial
83
+ specialization whose template parameter list is that of `A` and whose
84
+ template argument list is a specialization of `A` with the template
85
+ argument list of `A` [[temp.dep.type]] having a member typedef `type`
86
+ designating a template specialization with the template argument list of
87
+ `A` but with `C` as the template.
88
+
89
+ [*Note 1*: Equivalently, the template parameter list of the
90
+ specialization is that of `C`, the template argument list of the
91
+ specialization is `B`, and the member typedef names `C` with the
92
+ template argument list of `C`. — *end note*]
93
+
94
+ [*Example 1*:
95
+
96
+ ``` cpp
97
+ template <typename T> struct B {
98
+ B(T);
99
+ };
100
+ template <typename T> struct C : public B<T> {
101
+ using B<T>::B;
102
+ };
103
+ template <typename T> struct D : public B<T> {};
104
+
105
+ C c(42); // OK, deduces C<int>
106
+ D d(42); // error: deduction failed, no inherited deduction guides
107
+ B(int) -> B<char>;
108
+ C c2(42); // OK, deduces C<char>
109
+
110
+ template <typename T> struct E : public B<int> {
111
+ using B<int>::B;
112
+ };
113
+
114
+ E e(42); // error: deduction failed, arguments of E cannot be deduced from introduced guides
115
+
116
+ template <typename T, typename U, typename V> struct F {
117
+ F(T, U, V);
118
+ };
119
+ template <typename T, typename U> struct G : F<U, T, int> {
120
+ using G::F::F;
121
+ }
122
+
123
+ G g(true, 'a', 1); // OK, deduces G<char, bool>
124
+
125
+ template<class T, std::size_t N>
126
+ struct H {
127
+ T array[N];
128
+ };
129
+ template<class T, std::size_t N>
130
+ struct I {
131
+ volatile T array[N];
132
+ };
133
+ template<std::size_t N>
134
+ struct J {
135
+ unsigned char array[N];
136
+ };
137
+
138
+ H h = { "abc" }; // OK, deduces H<char, 4> (not T = const char)
139
+ I i = { "def" }; // OK, deduces I<char, 4>
140
+ J j = { "ghi" }; // error: cannot bind reference to array of unsigned char to array of char in deduction
141
+ ```
142
+
143
+ — *end example*]
144
 
145
  When resolving a placeholder for a deduced class type
146
  [[dcl.type.simple]] where the *template-name* names an alias template
147
  `A`, the *defining-type-id* of `A` must be of the form
148
 
 
154
  functions or function templates formed as follows. For each function or
155
  function template `f` in the guides of the template named by the
156
  *simple-template-id* of the *defining-type-id*, the template arguments
157
  of the return type of `f` are deduced from the *defining-type-id* of `A`
158
  according to the process in [[temp.deduct.type]] with the exception that
159
+ deduction does not fail if not all template arguments are deduced. If
160
+ deduction fails for another reason, proceed with an empty set of deduced
161
+ template arguments. Let `g` denote the result of substituting these
162
+ deductions into `f`. If substitution succeeds, form a function or
163
+ function template `f'` with the following properties and add it to the
164
+ set of guides of `A`:
165
 
166
  - The function type of `f'` is the function type of `g`.
167
  - If `f` is a function template, `f'` is a function template whose
168
  template parameter list consists of all the template parameters of `A`
169
  (including their default template arguments) that appear in the above
 
173
  function template.
174
  - The associated constraints [[temp.constr.decl]] are the conjunction of
175
  the associated constraints of `g` and a constraint that is satisfied
176
  if and only if the arguments of `A` are deducible (see below) from the
177
  return type.
178
+ - If `f` is a copy deduction candidate, then `f'` is considered to be so
179
+ as well.
180
+ - If `f` was generated from a *deduction-guide* [[temp.deduct.guide]],
181
+ then `f'` is considered to be so as well.
182
  - The *explicit-specifier* of `f'` is the *explicit-specifier* of `g`
183
  (if any).
184
 
185
  The arguments of a template `A` are said to be deducible from a type `T`
186
  if, given a class template
 
218
  *deduction-guide* that had an *explicit-specifier*, each such notional
219
  constructor is considered to have that same *explicit-specifier*. All
220
  such notional constructors are considered to be public members of the
221
  hypothetical class type.
222
 
223
+ [*Example 2*:
224
 
225
  ``` cpp
226
  template <class T> struct A {
227
  explicit A(const T&, ...) noexcept; // #1
228
  A(T&&, ...); // #2
 
300
  F f3 = {Types<X, Y, Z>{}, X{}, W{}}; // error: conflicting types deduced; operator Y not considered
301
  ```
302
 
303
  — *end example*]
304
 
305
+ [*Example 3*:
306
 
307
  ``` cpp
308
  template <class T, class U> struct C {
309
  C(T, U); // #1
310
  };
 
331
  template <class> class AA;
332
  template <class V> class AA<A<V>> { };
333
  template <class T> concept deduces_A = requires { sizeof(AA<T>); };
334
 
335
  // f1 is formed from the constructor #1 of C, generating the following function template
336
+ template<class T, class U>
337
  auto f1(T, U) -> C<T, U>;
338
 
339
  // Deducing arguments for C<T, U> from C<V *, V*> deduces T as V * and U as V *;
340
  // f1' is obtained by transforming f1 as described by the above procedure.
341
  template<class V> requires deduces_A<C<V *, V *>>