From Jason Turner

[temp.deduct.call]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp6czs86ta/{from.md → to.md} +145 -46
tmp/tmp6czs86ta/{from.md → to.md} RENAMED
@@ -1,35 +1,61 @@
1
  #### Deducing template arguments from a function call <a id="temp.deduct.call">[[temp.deduct.call]]</a>
2
 
3
  Template argument deduction is done by comparing each function template
4
- parameter type (call it `P`) with the type of the corresponding argument
5
- of the call (call it `A`) as described below. If removing references and
6
- cv-qualifiers from `P` gives `std::initializer_list<P^\prime>` for some
7
- `P^\prime` and the argument is an initializer list ([[dcl.init.list]]),
8
- then deduction is performed instead for each element of the initializer
9
- list, taking `P^\prime` as a function template parameter type and the
10
- initializer element as its argument. Otherwise, an initializer list
11
- argument causes the parameter to be considered a non-deduced context (
12
- [[temp.deduct.type]]).
 
 
 
 
 
13
 
14
  ``` cpp
15
  template<class T> void f(std::initializer_list<T>);
16
  f({1,2,3}); // T deduced to int
17
  f({1,"asdf"}); // error: T deduced to both int and const char*
18
 
19
  template<class T> void g(T);
20
  g({1,2,3}); // error: no argument deduced for T
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  ```
22
 
 
 
23
  For a function parameter pack that occurs at the end of the
24
- *parameter-declaration-list*, the type `A` of each remaining argument of
25
- the call is compared with the type `P` of the *declarator-id* of the
26
- function parameter pack. Each comparison deduces template arguments for
27
- subsequent positions in the template parameter packs expanded by the
28
- function parameter pack. When a function parameter pack appears in a
29
- non-deduced context ([[temp.deduct.type]]), the type of that parameter
30
- pack is never deduced.
 
 
31
 
32
  ``` cpp
33
  template<class ... Types> void f(Types& ...);
34
  template<class T1, class ... Types> void g(T1, Types ...);
35
  template<class T1, class ... Types> void g1(Types ..., T1);
@@ -38,107 +64,180 @@ void h(int x, float& y) {
38
  const int z = x;
39
  f(x, y, z); // Types is deduced to int, float, const int
40
  g(x, y, z); // T1 is deduced to int; Types is deduced to float, int
41
  g1(x, y, z); // error: Types is not deduced
42
  g1<int, int, int>(x, y, z); // OK, no deduction occurs
43
-
44
  }
45
  ```
46
 
 
 
47
  If `P` is not a reference type:
48
 
49
  - If `A` is an array type, the pointer type produced by the
50
  array-to-pointer standard conversion ([[conv.array]]) is used in
51
  place of `A` for type deduction; otherwise,
52
  - If `A` is a function type, the pointer type produced by the
53
  function-to-pointer standard conversion ([[conv.func]]) is used in
54
  place of `A` for type deduction; otherwise,
55
- - If `A` is a cv-qualified type, the top level cv-qualifiers of `A`’s
56
  type are ignored for type deduction.
57
 
58
- If `P` is a cv-qualified type, the top level cv-qualifiers of `P`’s type
59
  are ignored for type deduction. If `P` is a reference type, the type
60
- referred to by `P` is used for type deduction. If `P` is an rvalue
61
- reference to a cv-unqualified template parameter and the argument is an
62
- lvalue, the type “lvalue reference to `A`” is used in place of `A` for
63
- type deduction.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  ``` cpp
66
- template <class T> int f(T&&);
67
  template <class T> int g(const T&&);
68
  int i;
69
  int n1 = f(i); // calls f<int&>(int&)
70
  int n2 = f(0); // calls f<int>(int&&)
71
  int n3 = g(i); // error: would call g<int>(const int&&), which
72
  // would bind an rvalue reference to an lvalue
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  ```
74
 
 
 
75
  In general, the deduction process attempts to find template argument
76
  values that will make the deduced `A` identical to `A` (after the type
77
  `A` is transformed as described above). However, there are three cases
78
  that allow a difference:
79
 
80
  - If the original `P` is a reference type, the deduced `A` (i.e., the
81
  type referred to by the reference) can be more cv-qualified than the
82
  transformed `A`.
83
  - The transformed `A` can be another pointer or pointer to member type
84
- that can be converted to the deduced `A` via a qualification
85
- conversion ([[conv.qual]]).
 
86
  - If `P` is a class and `P` has the form *simple-template-id*, then the
87
  transformed `A` can be a derived class of the deduced `A`. Likewise,
88
  if `P` is a pointer to a class of the form *simple-template-id*, the
89
  transformed `A` can be a pointer to a derived class pointed to by the
90
  deduced `A`.
91
 
92
- as specified in  [[temp.arg.explicit]], implicit conversions will be
93
- performed on a function argument to convert it to the type of the
94
- corresponding function parameter if the parameter contains no
95
- *template-parameter*s that participate in template argument deduction.
96
- Such conversions are also allowed, in addition to the ones described in
97
- the preceding list.
98
-
99
  These alternatives are considered only if type deduction would otherwise
100
  fail. If they yield more than one possible deduced `A`, the type
101
- deduction fails. If a *template-parameter* is not used in any of the
102
- function parameters of a function template, or is used only in a
103
- non-deduced context, its corresponding *template-argument* cannot be
104
- deduced from a function call and the *template-argument* must be
105
- explicitly specified.
106
 
107
- When P is a function type, pointer to function type, or pointer to
108
- member function type:
 
 
 
 
 
 
109
 
110
  - If the argument is an overload set containing one or more function
111
  templates, the parameter is treated as a non-deduced context.
112
  - If the argument is an overload set (not containing function
113
  templates), trial argument deduction is attempted using each of the
114
  members of the set. If deduction succeeds for only one of the overload
115
  set members, that member is used as the argument value for the
116
  deduction. If deduction succeeds for more than one member of the
117
  overload set the parameter is treated as a non-deduced context.
 
 
 
118
  ``` cpp
119
- // Only one function of an overload set matches the call so the function
120
- // parameter is a deduced context.
121
  template <class T> int f(T (*p)(T));
122
  int g(int);
123
  int g(char);
124
  int i = f(g); // calls f(int (*)(int))
125
  ```
126
 
 
 
 
 
127
  ``` cpp
128
- // Ambiguous deduction causes the second function parameter to be a
129
- // non-deduced context.
130
  template <class T> int f(T, T (*p)(T));
131
  int g(int);
132
  char g(char);
133
  int i = f(1, g); // calls f(int, int (*)(int))
134
  ```
135
 
 
 
 
 
136
  ``` cpp
137
- // The overload set contains a template, causing the second function
138
- // parameter to be a non-deduced context.
139
  template <class T> int f(T, T (*p)(T));
140
  char g(char);
141
  template <class T> T g(T);
142
  int i = f(1, g); // calls f(int, int (*)(int))
143
  ```
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  #### Deducing template arguments from a function call <a id="temp.deduct.call">[[temp.deduct.call]]</a>
2
 
3
  Template argument deduction is done by comparing each function template
4
+ parameter type (call it `P`) that contains *template-parameter*s that
5
+ participate in template argument deduction with the type of the
6
+ corresponding argument of the call (call it `A`) as described below. If
7
+ removing references and cv-qualifiers from `P` gives
8
+ `std::initializer_list<P'>` or `P'[N]` for some `P'` and `N` and the
9
+ argument is a non-empty initializer list ([[dcl.init.list]]), then
10
+ deduction is performed instead for each element of the initializer list,
11
+ taking `P'` as a function template parameter type and the initializer
12
+ element as its argument, and in the `P'[N]` case, if `N` is a non-type
13
+ template parameter, `N` is deduced from the length of the initializer
14
+ list. Otherwise, an initializer list argument causes the parameter to be
15
+ considered a non-deduced context ([[temp.deduct.type]]).
16
+
17
+ [*Example 1*:
18
 
19
  ``` cpp
20
  template<class T> void f(std::initializer_list<T>);
21
  f({1,2,3}); // T deduced to int
22
  f({1,"asdf"}); // error: T deduced to both int and const char*
23
 
24
  template<class T> void g(T);
25
  g({1,2,3}); // error: no argument deduced for T
26
+
27
+ template<class T, int N> void h(T const(&)[N]);
28
+ h({1,2,3}); // T deduced to int, N deduced to 3
29
+
30
+ template<class T> void j(T const(&)[3]);
31
+ j({42}); // T deduced to int, array bound not considered
32
+
33
+ struct Aggr { int i; int j; };
34
+ template<int N> void k(Aggr const(&)[N]);
35
+ k({1,2,3}); // error: deduction fails, no conversion from int to Aggr
36
+ k({{1},{2},{3}}); // OK, N deduced to 3
37
+
38
+ template<int M, int N> void m(int const(&)[M][N]);
39
+ m({{1,2},{3,4}}); // M and N both deduced to 2
40
+
41
+ template<class T, int N> void n(T const(&)[N], T);
42
+ n({{1},{2},{3}},Aggr()); // OK, T is Aggr, N is 3
43
  ```
44
 
45
+ — *end example*]
46
+
47
  For a function parameter pack that occurs at the end of the
48
+ *parameter-declaration-list*, deduction is performed for each remaining
49
+ argument of the call, taking the type `P` of the *declarator-id* of the
50
+ function parameter pack as the corresponding function template parameter
51
+ type. Each deduction deduces template arguments for subsequent positions
52
+ in the template parameter packs expanded by the function parameter pack.
53
+ When a function parameter pack appears in a non-deduced context (
54
+ [[temp.deduct.type]]), the type of that parameter pack is never deduced.
55
+
56
+ [*Example 2*:
57
 
58
  ``` cpp
59
  template<class ... Types> void f(Types& ...);
60
  template<class T1, class ... Types> void g(T1, Types ...);
61
  template<class T1, class ... Types> void g1(Types ..., T1);
 
64
  const int z = x;
65
  f(x, y, z); // Types is deduced to int, float, const int
66
  g(x, y, z); // T1 is deduced to int; Types is deduced to float, int
67
  g1(x, y, z); // error: Types is not deduced
68
  g1<int, int, int>(x, y, z); // OK, no deduction occurs
 
69
  }
70
  ```
71
 
72
+ — *end example*]
73
+
74
  If `P` is not a reference type:
75
 
76
  - If `A` is an array type, the pointer type produced by the
77
  array-to-pointer standard conversion ([[conv.array]]) is used in
78
  place of `A` for type deduction; otherwise,
79
  - If `A` is a function type, the pointer type produced by the
80
  function-to-pointer standard conversion ([[conv.func]]) is used in
81
  place of `A` for type deduction; otherwise,
82
+ - If `A` is a cv-qualified type, the top-level cv-qualifiers of `A`’s
83
  type are ignored for type deduction.
84
 
85
+ If `P` is a cv-qualified type, the top-level cv-qualifiers of `P`’s type
86
  are ignored for type deduction. If `P` is a reference type, the type
87
+ referred to by `P` is used for type deduction.
88
+
89
+ [*Example 3*:
90
+
91
+ ``` cpp
92
+ template<class T> int f(const T&);
93
+ int n1 = f(5); // calls f<int>(const int&)
94
+ const int i = 0;
95
+ int n2 = f(i); // calls f<int>(const int&)
96
+ template <class T> int g(volatile T&);
97
+ int n3 = g(i); // calls g<const int>(const volatile int&)
98
+ ```
99
+
100
+ — *end example*]
101
+
102
+ A *forwarding reference* is an rvalue reference to a cv-unqualified
103
+ template parameter that does not represent a template parameter of a
104
+ class template (during class template argument deduction (
105
+ [[over.match.class.deduct]])). If `P` is a forwarding reference and the
106
+ argument is an lvalue, the type “lvalue reference to `A`” is used in
107
+ place of `A` for type deduction.
108
+
109
+ [*Example 4*:
110
 
111
  ``` cpp
112
+ template <class T> int f(T&& heisenreference);
113
  template <class T> int g(const T&&);
114
  int i;
115
  int n1 = f(i); // calls f<int&>(int&)
116
  int n2 = f(0); // calls f<int>(int&&)
117
  int n3 = g(i); // error: would call g<int>(const int&&), which
118
  // would bind an rvalue reference to an lvalue
119
+
120
+ template <class T> struct A {
121
+ template <class U>
122
+ A(T&&, U&&, int*); // #1: T&& is not a forwarding reference.
123
+ // U&& is a forwarding reference.
124
+ A(T&&, int*); // #2
125
+ };
126
+
127
+ template <class T> A(T&&, int*) -> A<T>; // #3: T&& is a forwarding reference.
128
+
129
+ int *ip;
130
+ A a{i, 0, ip}; // error: cannot deduce from #1
131
+ A a0{0, 0, ip}; // uses #1 to deduce A<int> and #1 to initialize
132
+ A a2{i, ip}; // uses #3 to deduce A<int&> and #2 to initialize
133
  ```
134
 
135
+ — *end example*]
136
+
137
  In general, the deduction process attempts to find template argument
138
  values that will make the deduced `A` identical to `A` (after the type
139
  `A` is transformed as described above). However, there are three cases
140
  that allow a difference:
141
 
142
  - If the original `P` is a reference type, the deduced `A` (i.e., the
143
  type referred to by the reference) can be more cv-qualified than the
144
  transformed `A`.
145
  - The transformed `A` can be another pointer or pointer to member type
146
+ that can be converted to the deduced `A` via a function pointer
147
+ conversion ([[conv.fctptr]]) and/or qualification conversion (
148
+ [[conv.qual]]).
149
  - If `P` is a class and `P` has the form *simple-template-id*, then the
150
  transformed `A` can be a derived class of the deduced `A`. Likewise,
151
  if `P` is a pointer to a class of the form *simple-template-id*, the
152
  transformed `A` can be a pointer to a derived class pointed to by the
153
  deduced `A`.
154
 
 
 
 
 
 
 
 
155
  These alternatives are considered only if type deduction would otherwise
156
  fail. If they yield more than one possible deduced `A`, the type
157
+ deduction fails.
 
 
 
 
158
 
159
+ [*Note 1*: If a *template-parameter* is not used in any of the function
160
+ parameters of a function template, or is used only in a non-deduced
161
+ context, its corresponding *template-argument* cannot be deduced from a
162
+ function call and the *template-argument* must be explicitly
163
+ specified. — *end note*]
164
+
165
+ When `P` is a function type, function pointer type, or pointer to member
166
+ function type:
167
 
168
  - If the argument is an overload set containing one or more function
169
  templates, the parameter is treated as a non-deduced context.
170
  - If the argument is an overload set (not containing function
171
  templates), trial argument deduction is attempted using each of the
172
  members of the set. If deduction succeeds for only one of the overload
173
  set members, that member is used as the argument value for the
174
  deduction. If deduction succeeds for more than one member of the
175
  overload set the parameter is treated as a non-deduced context.
176
+
177
+ [*Example 5*:
178
+
179
  ``` cpp
180
+ // Only one function of an overload set matches the call so the function parameter is a deduced context.
 
181
  template <class T> int f(T (*p)(T));
182
  int g(int);
183
  int g(char);
184
  int i = f(g); // calls f(int (*)(int))
185
  ```
186
 
187
+ — *end example*]
188
+
189
+ [*Example 6*:
190
+
191
  ``` cpp
192
+ // Ambiguous deduction causes the second function parameter to be a non-deduced context.
 
193
  template <class T> int f(T, T (*p)(T));
194
  int g(int);
195
  char g(char);
196
  int i = f(1, g); // calls f(int, int (*)(int))
197
  ```
198
 
199
+ — *end example*]
200
+
201
+ [*Example 7*:
202
+
203
  ``` cpp
204
+ // The overload set contains a template, causing the second function parameter to be a non-deduced context.
 
205
  template <class T> int f(T, T (*p)(T));
206
  char g(char);
207
  template <class T> T g(T);
208
  int i = f(1, g); // calls f(int, int (*)(int))
209
  ```
210
 
211
+ — *end example*]
212
+
213
+ If deduction succeeds for all parameters that contain
214
+ *template-parameter*s that participate in template argument deduction,
215
+ and all template arguments are explicitly specified, deduced, or
216
+ obtained from default template arguments, remaining parameters are then
217
+ compared with the corresponding arguments. For each remaining parameter
218
+ `P` with a type that was non-dependent before substitution of any
219
+ explicitly-specified template arguments, if the corresponding argument
220
+ `A` cannot be implicitly converted to `P`, deduction fails.
221
+
222
+ [*Note 2*: Parameters with dependent types in which no
223
+ *template-parameter*s participate in template argument deduction, and
224
+ parameters that became non-dependent due to substitution of
225
+ explicitly-specified template arguments, will be checked during overload
226
+ resolution. — *end note*]
227
+
228
+ [*Example 8*:
229
+
230
+ ``` cpp
231
+ template <class T> struct Z {
232
+ typedef typename T::x xx;
233
+ };
234
+ template <class T> typename Z<T>::xx f(void *, T); // #1
235
+ template <class T> void f(int, T); // #2
236
+ struct A {} a;
237
+ int main() {
238
+ f(1, a); // OK, deduction fails for #1 because there is no conversion from int to void*
239
+ }
240
+ ```
241
+
242
+ — *end example*]
243
+