tmp/tmpa9mnvfi_/{from.md → to.md}
RENAMED
|
@@ -1,21 +1,21 @@
|
|
| 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
|
| 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 |
-
|
| 9 |
-
and the argument is a non-empty initializer list
|
| 10 |
-
deduction is performed instead for each element
|
| 11 |
-
independently, taking `P`' as separate function
|
| 12 |
-
`P`'_i and the iᵗʰ initializer element as the
|
| 13 |
-
the `P`'`[N]` case, if `N` is a
|
| 14 |
-
deduced from the length of the initializer
|
| 15 |
-
initializer list argument causes the parameter to be
|
| 16 |
-
non-deduced context [[temp.deduct.type]].
|
| 17 |
|
| 18 |
[*Example 1*:
|
| 19 |
|
| 20 |
``` cpp
|
| 21 |
template<class T> void f(std::initializer_list<T>);
|
|
@@ -153,19 +153,20 @@ that allow a difference:
|
|
| 153 |
transformed `A`.
|
| 154 |
- The transformed `A` can be another pointer or pointer-to-member type
|
| 155 |
that can be converted to the deduced `A` via a function pointer
|
| 156 |
conversion [[conv.fctptr]] and/or qualification conversion
|
| 157 |
[[conv.qual]].
|
| 158 |
-
- If `P` is a class and `P` has the form *simple-template-id*
|
| 159 |
-
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
| 164 |
-
|
| 165 |
-
|
| 166 |
-
|
|
|
|
| 167 |
\[*Example 5*:
|
| 168 |
``` cpp
|
| 169 |
template <typename... T> struct X;
|
| 170 |
template <> struct X<> {};
|
| 171 |
template <typename T, typename... Ts>
|
|
@@ -184,11 +185,11 @@ that allow a difference:
|
|
| 184 |
|
| 185 |
These alternatives are considered only if type deduction would otherwise
|
| 186 |
fail. If they yield more than one possible deduced `A`, the type
|
| 187 |
deduction fails.
|
| 188 |
|
| 189 |
-
[*Note 1*: If a
|
| 190 |
parameters of a function template, or is used only in a non-deduced
|
| 191 |
context, its corresponding *template-argument* cannot be deduced from a
|
| 192 |
function call and the *template-argument* must be explicitly
|
| 193 |
specified. — *end note*]
|
| 194 |
|
|
@@ -197,14 +198,14 @@ pointer-to-member-function type:
|
|
| 197 |
|
| 198 |
- If the argument is an overload set containing one or more function
|
| 199 |
templates, the parameter is treated as a non-deduced context.
|
| 200 |
- If the argument is an overload set (not containing function
|
| 201 |
templates), trial argument deduction is attempted using each of the
|
| 202 |
-
members of the set
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
|
| 207 |
[*Example 6*:
|
| 208 |
|
| 209 |
``` cpp
|
| 210 |
// Only one function of an overload set matches the call so the function parameter is a deduced context.
|
|
@@ -238,5 +239,21 @@ template <class T> T g(T);
|
|
| 238 |
int i = f(1, g); // calls f(int, int (*)(int))
|
| 239 |
```
|
| 240 |
|
| 241 |
— *end example*]
|
| 242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 parameters 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 |
+
$\tcode{std::initializer_list<P}^{\prime}\tcode{>}$ or `P`'`[N]` for
|
| 9 |
+
some `P`' and `N` and the argument is a non-empty initializer list
|
| 10 |
+
[[dcl.init.list]], then deduction is performed instead for each element
|
| 11 |
+
of the initializer list independently, taking `P`' as separate function
|
| 12 |
+
template parameter types `P`'_i and the iᵗʰ initializer element as the
|
| 13 |
+
corresponding argument. In the `P`'`[N]` case, if `N` is a constant
|
| 14 |
+
template parameter, `N` is deduced from the length of the initializer
|
| 15 |
+
list. Otherwise, an initializer list argument causes the parameter to be
|
| 16 |
+
considered a non-deduced context [[temp.deduct.type]].
|
| 17 |
|
| 18 |
[*Example 1*:
|
| 19 |
|
| 20 |
``` cpp
|
| 21 |
template<class T> void f(std::initializer_list<T>);
|
|
|
|
| 153 |
transformed `A`.
|
| 154 |
- The transformed `A` can be another pointer or pointer-to-member type
|
| 155 |
that can be converted to the deduced `A` via a function pointer
|
| 156 |
conversion [[conv.fctptr]] and/or qualification conversion
|
| 157 |
[[conv.qual]].
|
| 158 |
+
- If `P` is a class and `P` has the form *simple-template-id* or
|
| 159 |
+
`typename`ₒₚₜ *splice-specialization-specifier*, then the transformed
|
| 160 |
+
`A` can be a derived class `D` of the deduced `A`. Likewise, if `P` is
|
| 161 |
+
a pointer to a class of the form *simple-template-id* or
|
| 162 |
+
`typename`ₒₚₜ *splice-specialization-specifier*, the transformed `A`
|
| 163 |
+
can be a pointer to a derived class `D` of the class pointed to by the
|
| 164 |
+
deduced `A`. However, if there is a class `C` that is a (direct or
|
| 165 |
+
indirect) base class of `D` and derived (directly or indirectly) from
|
| 166 |
+
a class `B` and that would be a valid deduced `A`, the deduced `A`
|
| 167 |
+
cannot be `B` or pointer to `B`, respectively.
|
| 168 |
\[*Example 5*:
|
| 169 |
``` cpp
|
| 170 |
template <typename... T> struct X;
|
| 171 |
template <> struct X<> {};
|
| 172 |
template <typename T, typename... Ts>
|
|
|
|
| 185 |
|
| 186 |
These alternatives are considered only if type deduction would otherwise
|
| 187 |
fail. If they yield more than one possible deduced `A`, the type
|
| 188 |
deduction fails.
|
| 189 |
|
| 190 |
+
[*Note 1*: If a template parameter is not used in any of the function
|
| 191 |
parameters of a function template, or is used only in a non-deduced
|
| 192 |
context, its corresponding *template-argument* cannot be deduced from a
|
| 193 |
function call and the *template-argument* must be explicitly
|
| 194 |
specified. — *end note*]
|
| 195 |
|
|
|
|
| 198 |
|
| 199 |
- If the argument is an overload set containing one or more function
|
| 200 |
templates, the parameter is treated as a non-deduced context.
|
| 201 |
- If the argument is an overload set (not containing function
|
| 202 |
templates), trial argument deduction is attempted using each of the
|
| 203 |
+
members of the set whose associated constraints [[temp.constr.constr]]
|
| 204 |
+
are satisfied. If all successful deductions yield the same deduced
|
| 205 |
+
`A`, that deduced `A` is the result of deduction; otherwise, the
|
| 206 |
+
parameter is treated as a non-deduced context.
|
| 207 |
|
| 208 |
[*Example 6*:
|
| 209 |
|
| 210 |
``` cpp
|
| 211 |
// Only one function of an overload set matches the call so the function parameter is a deduced context.
|
|
|
|
| 239 |
int i = f(1, g); // calls f(int, int (*)(int))
|
| 240 |
```
|
| 241 |
|
| 242 |
— *end example*]
|
| 243 |
|
| 244 |
+
[*Example 9*:
|
| 245 |
+
|
| 246 |
+
``` cpp
|
| 247 |
+
// All arguments for placeholder type deduction[dcl.type.auto.deduct] yield the same deduced type.
|
| 248 |
+
template<bool B> struct X {
|
| 249 |
+
static void f(short) requires B; // #1
|
| 250 |
+
static void f(short); // #2
|
| 251 |
+
};
|
| 252 |
+
void test() {
|
| 253 |
+
auto x = &X<true>::f; // OK, deduces void(*)(short), selects #1
|
| 254 |
+
auto y = &X<false>::f; // OK, deduces void(*)(short), selects #2
|
| 255 |
+
}
|
| 256 |
+
```
|
| 257 |
+
|
| 258 |
+
— *end example*]
|
| 259 |
+
|