tmp/tmp59_6jle2/{from.md → to.md}
RENAMED
|
@@ -3,18 +3,22 @@
|
|
| 3 |
Template argument deduction is done by comparing certain types
|
| 4 |
associated with the two function templates being compared.
|
| 5 |
|
| 6 |
Two sets of types are used to determine the partial ordering. For each
|
| 7 |
of the templates involved there is the original function type and the
|
| 8 |
-
transformed function type.
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
The types used to determine the ordering depend on the context in which
|
| 18 |
the partial ordering is done:
|
| 19 |
|
| 20 |
- In the context of a function call, the types used are those function
|
|
@@ -24,11 +28,13 @@ the partial ordering is done:
|
|
| 24 |
- In other contexts ([[temp.func.order]]) the function template’s
|
| 25 |
function type is used.
|
| 26 |
|
| 27 |
Each type nominated above from the parameter template and the
|
| 28 |
corresponding type from the argument template are used as the types of
|
| 29 |
-
`P` and `A`.
|
|
|
|
|
|
|
| 30 |
|
| 31 |
Before the partial ordering is done, certain transformations are
|
| 32 |
performed on the types used for partial ordering:
|
| 33 |
|
| 34 |
- If `P` is a reference type, `P` is replaced by the type referred to.
|
|
@@ -45,70 +51,88 @@ Remove any top-level cv-qualifiers:
|
|
| 45 |
- If `P` is a cv-qualified type, `P` is replaced by the cv-unqualified
|
| 46 |
version of `P`.
|
| 47 |
- If `A` is a cv-qualified type, `A` is replaced by the cv-unqualified
|
| 48 |
version of `A`.
|
| 49 |
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
deduction succeeds for a given type,
|
| 59 |
-
is considered to be at least as
|
| 60 |
-
parameter template.
|
|
|
|
|
|
|
| 61 |
|
| 62 |
``` cpp
|
| 63 |
template<class... Args> void f(Args... args); // #1
|
| 64 |
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
|
| 65 |
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
|
| 66 |
|
| 67 |
f(); // calls #1
|
| 68 |
f(1, 2, 3); // calls #2
|
| 69 |
-
f(1, 2);
|
| 70 |
-
|
| 71 |
```
|
| 72 |
|
|
|
|
|
|
|
| 73 |
If, for a given type, deduction succeeds in both directions (i.e., the
|
| 74 |
types are identical after the transformations above) and both `P` and
|
| 75 |
`A` were reference types (before being replaced with the type referred
|
| 76 |
to above):
|
| 77 |
|
| 78 |
- if the type from the argument template was an lvalue reference and the
|
| 79 |
-
type from the parameter template was not, the
|
| 80 |
-
considered to be
|
|
|
|
| 81 |
- if the type from the argument template is more cv-qualified than the
|
| 82 |
-
type from the parameter template (as described above), the
|
| 83 |
-
type is considered to be
|
| 84 |
-
|
| 85 |
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 92 |
|
| 93 |
In most cases, all template parameters must have values in order for
|
| 94 |
deduction to succeed, but for partial ordering purposes a template
|
| 95 |
parameter may remain without a value provided it is not used in the
|
| 96 |
-
types being used for partial ordering.
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
``` cpp
|
| 100 |
template <class T> T f(int); // #1
|
| 101 |
template <class T, class U> T f(U); // #2
|
| 102 |
void g() {
|
| 103 |
f<int>(1); // calls #1
|
| 104 |
}
|
| 105 |
```
|
| 106 |
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
|
| 111 |
``` cpp
|
| 112 |
template<class ...> struct Tuple { };
|
| 113 |
template<class ... Types> void g(Tuple<Types ...>); // #1
|
| 114 |
template<class T1, class ... Types> void g(Tuple<T1, Types ...>); // #2
|
|
@@ -118,5 +142,7 @@ g(Tuple<>()); // calls #1
|
|
| 118 |
g(Tuple<int, float>()); // calls #2
|
| 119 |
g(Tuple<int, float&>()); // calls #3
|
| 120 |
g(Tuple<int>()); // calls #3
|
| 121 |
```
|
| 122 |
|
|
|
|
|
|
|
|
|
| 3 |
Template argument deduction is done by comparing certain types
|
| 4 |
associated with the two function templates being compared.
|
| 5 |
|
| 6 |
Two sets of types are used to determine the partial ordering. For each
|
| 7 |
of the templates involved there is the original function type and the
|
| 8 |
+
transformed function type.
|
| 9 |
+
|
| 10 |
+
[*Note 1*: The creation of the transformed type is described in
|
| 11 |
+
[[temp.func.order]]. — *end note*]
|
| 12 |
+
|
| 13 |
+
The deduction process uses the transformed type as the argument template
|
| 14 |
+
and the original type of the other template as the parameter template.
|
| 15 |
+
This process is done twice for each type involved in the partial
|
| 16 |
+
ordering comparison: once using the transformed template-1 as the
|
| 17 |
+
argument template and template-2 as the parameter template and again
|
| 18 |
+
using the transformed template-2 as the argument template and template-1
|
| 19 |
+
as the parameter template.
|
| 20 |
|
| 21 |
The types used to determine the ordering depend on the context in which
|
| 22 |
the partial ordering is done:
|
| 23 |
|
| 24 |
- In the context of a function call, the types used are those function
|
|
|
|
| 28 |
- In other contexts ([[temp.func.order]]) the function template’s
|
| 29 |
function type is used.
|
| 30 |
|
| 31 |
Each type nominated above from the parameter template and the
|
| 32 |
corresponding type from the argument template are used as the types of
|
| 33 |
+
`P` and `A`. If a particular `P` contains no *template-parameter*s that
|
| 34 |
+
participate in template argument deduction, that `P` is not used to
|
| 35 |
+
determine the ordering.
|
| 36 |
|
| 37 |
Before the partial ordering is done, certain transformations are
|
| 38 |
performed on the types used for partial ordering:
|
| 39 |
|
| 40 |
- If `P` is a reference type, `P` is replaced by the type referred to.
|
|
|
|
| 51 |
- If `P` is a cv-qualified type, `P` is replaced by the cv-unqualified
|
| 52 |
version of `P`.
|
| 53 |
- If `A` is a cv-qualified type, `A` is replaced by the cv-unqualified
|
| 54 |
version of `A`.
|
| 55 |
|
| 56 |
+
Using the resulting types `P` and `A`, the deduction is then done as
|
| 57 |
+
described in [[temp.deduct.type]]. If `P` is a function parameter pack,
|
| 58 |
+
the type `A` of each remaining parameter type of the argument template
|
| 59 |
+
is compared with the type `P` of the *declarator-id* of the function
|
| 60 |
+
parameter pack. Each comparison deduces template arguments for
|
| 61 |
+
subsequent positions in the template parameter packs expanded by the
|
| 62 |
+
function parameter pack. Similarly, if `A` was transformed from a
|
| 63 |
+
function parameter pack, it is compared with each remaining parameter
|
| 64 |
+
type of the parameter template. If deduction succeeds for a given type,
|
| 65 |
+
the type from the argument template is considered to be at least as
|
| 66 |
+
specialized as the type from the parameter template.
|
| 67 |
+
|
| 68 |
+
[*Example 1*:
|
| 69 |
|
| 70 |
``` cpp
|
| 71 |
template<class... Args> void f(Args... args); // #1
|
| 72 |
template<class T1, class... Args> void f(T1 a1, Args... args); // #2
|
| 73 |
template<class T1, class T2> void f(T1 a1, T2 a2); // #3
|
| 74 |
|
| 75 |
f(); // calls #1
|
| 76 |
f(1, 2, 3); // calls #2
|
| 77 |
+
f(1, 2); // calls #3; non-variadic template #3 is more specialized
|
| 78 |
+
// than the variadic templates #1 and #2
|
| 79 |
```
|
| 80 |
|
| 81 |
+
— *end example*]
|
| 82 |
+
|
| 83 |
If, for a given type, deduction succeeds in both directions (i.e., the
|
| 84 |
types are identical after the transformations above) and both `P` and
|
| 85 |
`A` were reference types (before being replaced with the type referred
|
| 86 |
to above):
|
| 87 |
|
| 88 |
- if the type from the argument template was an lvalue reference and the
|
| 89 |
+
type from the parameter template was not, the parameter type is not
|
| 90 |
+
considered to be at least as specialized as the argument type;
|
| 91 |
+
otherwise,
|
| 92 |
- if the type from the argument template is more cv-qualified than the
|
| 93 |
+
type from the parameter template (as described above), the parameter
|
| 94 |
+
type is not considered to be at least as specialized as the argument
|
| 95 |
+
type.
|
| 96 |
|
| 97 |
+
Function template `F` is *at least as specialized as* function template
|
| 98 |
+
`G` if, for each pair of types used to determine the ordering, the type
|
| 99 |
+
from `F` is at least as specialized as the type from `G`. `F` is *more
|
| 100 |
+
specialized than* `G` if `F` is at least as specialized as `G` and `G`
|
| 101 |
+
is not at least as specialized as `F`.
|
| 102 |
+
|
| 103 |
+
If, after considering the above, function template `F` is at least as
|
| 104 |
+
specialized as function template `G` and vice-versa, and if `G` has a
|
| 105 |
+
trailing parameter pack for which `F` does not have a corresponding
|
| 106 |
+
parameter, and if `F` does not have a trailing parameter pack, then `F`
|
| 107 |
+
is more specialized than `G`.
|
| 108 |
|
| 109 |
In most cases, all template parameters must have values in order for
|
| 110 |
deduction to succeed, but for partial ordering purposes a template
|
| 111 |
parameter may remain without a value provided it is not used in the
|
| 112 |
+
types being used for partial ordering.
|
| 113 |
+
|
| 114 |
+
[*Note 2*: A template parameter used in a non-deduced context is
|
| 115 |
+
considered used. — *end note*]
|
| 116 |
+
|
| 117 |
+
[*Example 2*:
|
| 118 |
|
| 119 |
``` cpp
|
| 120 |
template <class T> T f(int); // #1
|
| 121 |
template <class T, class U> T f(U); // #2
|
| 122 |
void g() {
|
| 123 |
f<int>(1); // calls #1
|
| 124 |
}
|
| 125 |
```
|
| 126 |
|
| 127 |
+
— *end example*]
|
| 128 |
+
|
| 129 |
+
[*Note 3*: Partial ordering of function templates containing template
|
| 130 |
+
parameter packs is independent of the number of deduced arguments for
|
| 131 |
+
those template parameter packs. — *end note*]
|
| 132 |
+
|
| 133 |
+
[*Example 3*:
|
| 134 |
|
| 135 |
``` cpp
|
| 136 |
template<class ...> struct Tuple { };
|
| 137 |
template<class ... Types> void g(Tuple<Types ...>); // #1
|
| 138 |
template<class T1, class ... Types> void g(Tuple<T1, Types ...>); // #2
|
|
|
|
| 142 |
g(Tuple<int, float>()); // calls #2
|
| 143 |
g(Tuple<int, float&>()); // calls #3
|
| 144 |
g(Tuple<int>()); // calls #3
|
| 145 |
```
|
| 146 |
|
| 147 |
+
— *end example*]
|
| 148 |
+
|