- 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`)
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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*,
|
| 25 |
-
the call
|
| 26 |
-
function parameter pack
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
non-deduced context (
|
| 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
|
| 56 |
type are ignored for type deduction.
|
| 57 |
|
| 58 |
-
If `P` is a cv-qualified type, the top
|
| 59 |
are ignored for type deduction. If `P` is a reference type, the type
|
| 60 |
-
referred to by `P` is used for type deduction.
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 85 |
-
conversion ([[conv.
|
|
|
|
| 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.
|
| 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 |
-
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 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 |
-
|
| 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 |
-
|
| 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 |
+
|