tmp/tmpf4vs5g58/{from.md → to.md}
RENAMED
|
@@ -1,49 +1,60 @@
|
|
| 1 |
#### Partial ordering of function templates <a id="temp.func.order">[[temp.func.order]]</a>
|
| 2 |
|
| 3 |
If a function template is overloaded, the use of a function template
|
| 4 |
-
specialization might be ambiguous because template argument deduction
|
| 5 |
-
[[temp.deduct]]
|
| 6 |
more than one function template declaration. *Partial ordering* of
|
| 7 |
overloaded function template declarations is used in the following
|
| 8 |
contexts to select the function template to which a function template
|
| 9 |
specialization refers:
|
| 10 |
|
| 11 |
- during overload resolution for a call to a function template
|
| 12 |
-
specialization
|
| 13 |
- when the address of a function template specialization is taken;
|
| 14 |
- when a placement operator delete that is a function template
|
| 15 |
specialization is selected to match a placement operator new (
|
| 16 |
[[basic.stc.dynamic.deallocation]], [[expr.new]]);
|
| 17 |
-
- when a friend function declaration
|
| 18 |
-
instantiation
|
| 19 |
-
[[temp.expl.spec]]
|
| 20 |
|
| 21 |
Partial ordering selects which of two function templates is more
|
| 22 |
specialized than the other by transforming each template in turn (see
|
| 23 |
next paragraph) and performing template argument deduction using the
|
| 24 |
function type. The deduction process determines whether one of the
|
| 25 |
templates is more specialized than the other. If so, the more
|
| 26 |
specialized template is the one chosen by the partial ordering process.
|
|
|
|
|
|
|
| 27 |
|
| 28 |
To produce the transformed template, for each type, non-type, or
|
| 29 |
-
template template parameter (including template parameter packs
|
| 30 |
-
[[temp.variadic]]
|
| 31 |
template respectively and substitute it for each occurrence of that
|
| 32 |
parameter in the function type of the template.
|
| 33 |
|
| 34 |
[*Note 1*: The type replacing the placeholder in the type of the value
|
| 35 |
synthesized for a non-type template parameter is also a unique
|
| 36 |
synthesized type. — *end note*]
|
| 37 |
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
[*Note 2*: This allows a non-static member to be ordered with respect
|
| 47 |
to a non-member function and for the results to be equivalent to the
|
| 48 |
ordering of two equivalent non-members. — *end note*]
|
| 49 |
|
|
@@ -61,11 +72,11 @@ template<class T, class R> int operator*(T&, R&); // #2
|
|
| 61 |
// template<class R> int operator*(B<A>&, R&);\quad\quad\quad// #1a
|
| 62 |
|
| 63 |
int main() {
|
| 64 |
A a;
|
| 65 |
B<A> b;
|
| 66 |
-
b * a; // calls #
|
| 67 |
}
|
| 68 |
```
|
| 69 |
|
| 70 |
— *end example*]
|
| 71 |
|
|
@@ -102,12 +113,12 @@ void m() {
|
|
| 102 |
|
| 103 |
— *end example*]
|
| 104 |
|
| 105 |
[*Note 3*:
|
| 106 |
|
| 107 |
-
Since
|
| 108 |
-
which there are explicit call arguments, some parameters are ignored
|
| 109 |
(namely, function parameter packs, parameters with default arguments,
|
| 110 |
and ellipsis parameters).
|
| 111 |
|
| 112 |
[*Example 3*:
|
| 113 |
|
|
@@ -154,14 +165,75 @@ template<class T, class... U> void f(T, U...); // #1
|
|
| 154 |
template<class T > void f(T); // #2
|
| 155 |
template<class T, class... U> void g(T*, U...); // #3
|
| 156 |
template<class T > void g(T); // #4
|
| 157 |
|
| 158 |
void h(int i) {
|
| 159 |
-
f(&i); //
|
| 160 |
g(&i); // OK: calls #3
|
| 161 |
}
|
| 162 |
```
|
| 163 |
|
| 164 |
— *end example*]
|
| 165 |
|
| 166 |
— *end note*]
|
| 167 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
#### Partial ordering of function templates <a id="temp.func.order">[[temp.func.order]]</a>
|
| 2 |
|
| 3 |
If a function template is overloaded, the use of a function template
|
| 4 |
+
specialization might be ambiguous because template argument deduction
|
| 5 |
+
[[temp.deduct]] may associate the function template specialization with
|
| 6 |
more than one function template declaration. *Partial ordering* of
|
| 7 |
overloaded function template declarations is used in the following
|
| 8 |
contexts to select the function template to which a function template
|
| 9 |
specialization refers:
|
| 10 |
|
| 11 |
- during overload resolution for a call to a function template
|
| 12 |
+
specialization [[over.match.best]];
|
| 13 |
- when the address of a function template specialization is taken;
|
| 14 |
- when a placement operator delete that is a function template
|
| 15 |
specialization is selected to match a placement operator new (
|
| 16 |
[[basic.stc.dynamic.deallocation]], [[expr.new]]);
|
| 17 |
+
- when a friend function declaration [[temp.friend]], an explicit
|
| 18 |
+
instantiation [[temp.explicit]] or an explicit specialization
|
| 19 |
+
[[temp.expl.spec]] refers to a function template specialization.
|
| 20 |
|
| 21 |
Partial ordering selects which of two function templates is more
|
| 22 |
specialized than the other by transforming each template in turn (see
|
| 23 |
next paragraph) and performing template argument deduction using the
|
| 24 |
function type. The deduction process determines whether one of the
|
| 25 |
templates is more specialized than the other. If so, the more
|
| 26 |
specialized template is the one chosen by the partial ordering process.
|
| 27 |
+
If both deductions succeed, the partial ordering selects the more
|
| 28 |
+
constrained template (if one exists) as determined below.
|
| 29 |
|
| 30 |
To produce the transformed template, for each type, non-type, or
|
| 31 |
+
template template parameter (including template parameter packs
|
| 32 |
+
[[temp.variadic]] thereof) synthesize a unique type, value, or class
|
| 33 |
template respectively and substitute it for each occurrence of that
|
| 34 |
parameter in the function type of the template.
|
| 35 |
|
| 36 |
[*Note 1*: The type replacing the placeholder in the type of the value
|
| 37 |
synthesized for a non-type template parameter is also a unique
|
| 38 |
synthesized type. — *end note*]
|
| 39 |
|
| 40 |
+
Each function template M that is a member function is considered to have
|
| 41 |
+
a new first parameter of type X(M), described below, inserted in its
|
| 42 |
+
function parameter list. If exactly one of the function templates was
|
| 43 |
+
considered by overload resolution via a rewritten candidate
|
| 44 |
+
[[over.match.oper]] with a reversed order of parameters, then the order
|
| 45 |
+
of the function parameters in its transformed template is reversed. For
|
| 46 |
+
a function template M with cv-qualifiers cv that is a member of a class
|
| 47 |
+
A:
|
| 48 |
+
|
| 49 |
+
- The type X(M) is “rvalue reference to cv A” if the optional
|
| 50 |
+
*ref-qualifier* of M is `&&` or if M has no *ref-qualifier* and the
|
| 51 |
+
positionally-corresponding parameter of the other transformed template
|
| 52 |
+
has rvalue reference type; if this determination depends recursively
|
| 53 |
+
upon whether X(M) is an rvalue reference type, it is not considered to
|
| 54 |
+
have rvalue reference type.
|
| 55 |
+
- Otherwise, X(M) is “lvalue reference to cv A”.
|
| 56 |
|
| 57 |
[*Note 2*: This allows a non-static member to be ordered with respect
|
| 58 |
to a non-member function and for the results to be equivalent to the
|
| 59 |
ordering of two equivalent non-members. — *end note*]
|
| 60 |
|
|
|
|
| 72 |
// template<class R> int operator*(B<A>&, R&);\quad\quad\quad// #1a
|
| 73 |
|
| 74 |
int main() {
|
| 75 |
A a;
|
| 76 |
B<A> b;
|
| 77 |
+
b * a; // calls #1
|
| 78 |
}
|
| 79 |
```
|
| 80 |
|
| 81 |
— *end example*]
|
| 82 |
|
|
|
|
| 113 |
|
| 114 |
— *end example*]
|
| 115 |
|
| 116 |
[*Note 3*:
|
| 117 |
|
| 118 |
+
Since, in a call context, such type deduction considers only parameters
|
| 119 |
+
for which there are explicit call arguments, some parameters are ignored
|
| 120 |
(namely, function parameter packs, parameters with default arguments,
|
| 121 |
and ellipsis parameters).
|
| 122 |
|
| 123 |
[*Example 3*:
|
| 124 |
|
|
|
|
| 165 |
template<class T > void f(T); // #2
|
| 166 |
template<class T, class... U> void g(T*, U...); // #3
|
| 167 |
template<class T > void g(T); // #4
|
| 168 |
|
| 169 |
void h(int i) {
|
| 170 |
+
f(&i); // OK: calls #2
|
| 171 |
g(&i); // OK: calls #3
|
| 172 |
}
|
| 173 |
```
|
| 174 |
|
| 175 |
— *end example*]
|
| 176 |
|
| 177 |
— *end note*]
|
| 178 |
|
| 179 |
+
If deduction against the other template succeeds for both transformed
|
| 180 |
+
templates, constraints can be considered as follows:
|
| 181 |
+
|
| 182 |
+
- If their *template-parameter-list*s (possibly including
|
| 183 |
+
*template-parameter*s invented for an abbreviated function template
|
| 184 |
+
[[dcl.fct]]) or function parameter lists differ in length, neither
|
| 185 |
+
template is more specialized than the other.
|
| 186 |
+
- Otherwise:
|
| 187 |
+
- If exactly one of the templates was considered by overload
|
| 188 |
+
resolution via a rewritten candidate with reversed order of
|
| 189 |
+
parameters:
|
| 190 |
+
- If, for either template, some of the template parameters are not
|
| 191 |
+
deducible from their function parameters, neither template is more
|
| 192 |
+
specialized than the other.
|
| 193 |
+
- If there is either no reordering or more than one reordering of
|
| 194 |
+
the associated *template-parameter-list* such that
|
| 195 |
+
- the corresponding *template-parameter*s of the
|
| 196 |
+
*template-parameter-list*s are equivalent and
|
| 197 |
+
- the function parameters that positionally correspond between the
|
| 198 |
+
two templates are of the same type,
|
| 199 |
+
|
| 200 |
+
neither template is more specialized than the other.
|
| 201 |
+
- Otherwise, if the corresponding *template-parameter*s of the
|
| 202 |
+
*template-parameter-list*s are not equivalent [[temp.over.link]] or
|
| 203 |
+
if the function parameters that positionally correspond between the
|
| 204 |
+
two templates are not of the same type, neither template is more
|
| 205 |
+
specialized than the other.
|
| 206 |
+
- Otherwise, if the context in which the partial ordering is done is
|
| 207 |
+
that of a call to a conversion function and the return types of the
|
| 208 |
+
templates are not the same, then neither template is more specialized
|
| 209 |
+
than the other.
|
| 210 |
+
- Otherwise, if one template is more constrained than the other
|
| 211 |
+
[[temp.constr.order]], the more constrained template is more
|
| 212 |
+
specialized than the other.
|
| 213 |
+
- Otherwise, neither template is more specialized than the other.
|
| 214 |
+
|
| 215 |
+
[*Example 6*:
|
| 216 |
+
|
| 217 |
+
``` cpp
|
| 218 |
+
template <typename> constexpr bool True = true;
|
| 219 |
+
template <typename T> concept C = True<T>;
|
| 220 |
+
|
| 221 |
+
void f(C auto &, auto &) = delete;
|
| 222 |
+
template <C Q> void f(Q &, C auto &);
|
| 223 |
+
|
| 224 |
+
void g(struct A *ap, struct B *bp) {
|
| 225 |
+
f(*ap, *bp); // OK: Can use different methods to produce template parameters
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
template <typename T, typename U> struct X {};
|
| 229 |
+
|
| 230 |
+
template <typename T, C U, typename V> bool operator==(X<T, U>, V) = delete;
|
| 231 |
+
template <C T, C U, C V> bool operator==(T, X<U, V>);
|
| 232 |
+
|
| 233 |
+
void h() {
|
| 234 |
+
X<void *, int>{} == 0; // OK: Correspondence of [T, U, V] and [U, V, T]
|
| 235 |
+
}
|
| 236 |
+
```
|
| 237 |
+
|
| 238 |
+
— *end example*]
|
| 239 |
+
|