tmp/tmpt65_mb8g/{from.md → to.md}
RENAMED
|
@@ -1,25 +1,30 @@
|
|
| 1 |
### Function templates <a id="temp.fct">[[temp.fct]]</a>
|
| 2 |
|
|
|
|
|
|
|
| 3 |
A function template defines an unbounded set of related functions.
|
| 4 |
|
| 5 |
[*Example 1*:
|
| 6 |
|
| 7 |
-
A family of sort functions
|
| 8 |
|
| 9 |
``` cpp
|
| 10 |
template<class T> class Array { };
|
| 11 |
template<class T> void sort(Array<T>&);
|
| 12 |
```
|
| 13 |
|
| 14 |
— *end example*]
|
| 15 |
|
| 16 |
-
A function template can
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
|
|
|
|
|
|
|
|
|
| 21 |
|
| 22 |
#### Function template overloading <a id="temp.over.link">[[temp.over.link]]</a>
|
| 23 |
|
| 24 |
It is possible to overload function templates so that two different
|
| 25 |
function template specializations have the same type.
|
|
@@ -54,17 +59,17 @@ names of the template parameters are significant only for establishing
|
|
| 54 |
the relationship between the template parameters and the rest of the
|
| 55 |
signature.
|
| 56 |
|
| 57 |
[*Note 1*:
|
| 58 |
|
| 59 |
-
Two distinct function templates
|
| 60 |
and function parameter lists, even if overload resolution alone cannot
|
| 61 |
distinguish them.
|
| 62 |
|
| 63 |
``` cpp
|
| 64 |
template<class T> void f();
|
| 65 |
-
template<int I> void f(); // OK
|
| 66 |
// distinguishable with an explicit template argument list
|
| 67 |
```
|
| 68 |
|
| 69 |
— *end note*]
|
| 70 |
|
|
@@ -101,25 +106,27 @@ another token that names the same template parameter in the other
|
|
| 101 |
expression. Two unevaluated operands that do not involve template
|
| 102 |
parameters are considered equivalent if two function definitions
|
| 103 |
containing the expressions would satisfy the one-definition rule, except
|
| 104 |
that the tokens used to name types and declarations may differ as long
|
| 105 |
as they name the same entities, and the tokens used to form concept-ids
|
| 106 |
-
may differ as long as the two *template-id*s are the same
|
|
|
|
| 107 |
|
| 108 |
[*Note 3*: For instance, `A<42>` and `A<40+2>` name the same
|
| 109 |
type. — *end note*]
|
| 110 |
|
| 111 |
Two *lambda-expression*s are never considered equivalent.
|
| 112 |
|
| 113 |
[*Note 4*: The intent is to avoid *lambda-expression*s appearing in the
|
| 114 |
signature of a function template with external linkage. — *end note*]
|
| 115 |
|
| 116 |
For determining whether two dependent names [[temp.dep]] are equivalent,
|
| 117 |
-
only the name itself is considered, not the result of name lookup
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
first declaration
|
|
|
|
| 121 |
|
| 122 |
[*Example 3*:
|
| 123 |
|
| 124 |
``` cpp
|
| 125 |
template <int I, int J> void f(A<I+J>); // #1
|
|
@@ -128,11 +135,11 @@ template <int K, int L> void f(A<K+L>); // same as #1
|
|
| 128 |
template <class T> decltype(g(T())) h();
|
| 129 |
int g(int);
|
| 130 |
template <class T> decltype(g(T())) h() // redeclaration of h() uses the earlier lookup…
|
| 131 |
{ return g(T()); } // …{} although the lookup here does find g(int)
|
| 132 |
int i = h<int>(); // template argument substitution fails; g(int)
|
| 133 |
-
//
|
| 134 |
|
| 135 |
// ill-formed, no diagnostic required: the two expressions are functionally equivalent but not equivalent
|
| 136 |
template <int N> void foo(const char (*s)[([]{}, N)]);
|
| 137 |
template <int N> void foo(const char (*s)[([]{}, N)]);
|
| 138 |
|
|
@@ -149,13 +156,25 @@ of template arguments, the evaluation of the expression results in the
|
|
| 149 |
same value. Two unevaluated operands that are not equivalent are
|
| 150 |
functionally equivalent if, for any given set of template arguments, the
|
| 151 |
expressions perform the same operations in the same order with the same
|
| 152 |
entities.
|
| 153 |
|
| 154 |
-
[*Note
|
| 155 |
parentheses. — *end note*]
|
| 156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
Two *template-head*s are *equivalent* if their
|
| 158 |
*template-parameter-list*s have the same length, corresponding
|
| 159 |
*template-parameter*s are equivalent and are both declared with
|
| 160 |
*type-constraint*s that are equivalent if either *template-parameter* is
|
| 161 |
declared with a *type-constraint*, and if either *template-head* has a
|
|
@@ -175,25 +194,24 @@ When determining whether types or *type-constraint*s are equivalent, the
|
|
| 175 |
rules above are used to compare expressions involving template
|
| 176 |
parameters. Two *template-head*s are *functionally equivalent* if they
|
| 177 |
accept and are satisfied by [[temp.constr.constr]] the same set of
|
| 178 |
template argument lists.
|
| 179 |
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
expressions involving template parameters. Two function templates are
|
| 185 |
-
*functionally equivalent* if they are declared in the same scope, have
|
| 186 |
-
the same name, accept and are satisfied by the same set of template
|
| 187 |
-
argument lists, and have return types and parameter lists that are
|
| 188 |
-
functionally equivalent using the rules described above to compare
|
| 189 |
-
expressions involving template parameters. If the validity or meaning of
|
| 190 |
-
the program depends on whether two constructs are equivalent, and they
|
| 191 |
-
are functionally equivalent but not equivalent, the program is
|
| 192 |
-
ill-formed, no diagnostic required.
|
| 193 |
|
| 194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
|
| 196 |
This rule guarantees that equivalent declarations will be linked with
|
| 197 |
one another, while not requiring implementations to use heroic efforts
|
| 198 |
to guarantee that functionally equivalent declarations will be treated
|
| 199 |
as distinct. For example, the last two declarations are functionally
|
|
@@ -215,24 +233,23 @@ template <int I> void f(A<I>, A<I+1+2+3+4>);
|
|
| 215 |
|
| 216 |
— *end note*]
|
| 217 |
|
| 218 |
#### Partial ordering of function templates <a id="temp.func.order">[[temp.func.order]]</a>
|
| 219 |
|
| 220 |
-
If
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
specialization refers:
|
| 227 |
|
| 228 |
- during overload resolution for a call to a function template
|
| 229 |
specialization [[over.match.best]];
|
| 230 |
- when the address of a function template specialization is taken;
|
| 231 |
- when a placement operator delete that is a function template
|
| 232 |
-
specialization is selected to match a placement operator new
|
| 233 |
-
[[basic.stc.dynamic.deallocation]], [[expr.new]]
|
| 234 |
- when a friend function declaration [[temp.friend]], an explicit
|
| 235 |
instantiation [[temp.explicit]] or an explicit specialization
|
| 236 |
[[temp.expl.spec]] refers to a function template specialization.
|
| 237 |
|
| 238 |
Partial ordering selects which of two function templates is more
|
|
@@ -382,12 +399,12 @@ template<class T, class... U> void f(T, U...); // #1
|
|
| 382 |
template<class T > void f(T); // #2
|
| 383 |
template<class T, class... U> void g(T*, U...); // #3
|
| 384 |
template<class T > void g(T); // #4
|
| 385 |
|
| 386 |
void h(int i) {
|
| 387 |
-
f(&i); // OK
|
| 388 |
-
g(&i); // OK
|
| 389 |
}
|
| 390 |
```
|
| 391 |
|
| 392 |
— *end example*]
|
| 393 |
|
|
@@ -437,20 +454,20 @@ template <typename T> concept C = True<T>;
|
|
| 437 |
|
| 438 |
void f(C auto &, auto &) = delete;
|
| 439 |
template <C Q> void f(Q &, C auto &);
|
| 440 |
|
| 441 |
void g(struct A *ap, struct B *bp) {
|
| 442 |
-
f(*ap, *bp); // OK
|
| 443 |
}
|
| 444 |
|
| 445 |
template <typename T, typename U> struct X {};
|
| 446 |
|
| 447 |
template <typename T, C U, typename V> bool operator==(X<T, U>, V) = delete;
|
| 448 |
template <C T, C U, C V> bool operator==(T, X<U, V>);
|
| 449 |
|
| 450 |
void h() {
|
| 451 |
-
X<void *, int>{} == 0; // OK
|
| 452 |
}
|
| 453 |
```
|
| 454 |
|
| 455 |
— *end example*]
|
| 456 |
|
|
|
|
| 1 |
### Function templates <a id="temp.fct">[[temp.fct]]</a>
|
| 2 |
|
| 3 |
+
#### General <a id="temp.fct.general">[[temp.fct.general]]</a>
|
| 4 |
+
|
| 5 |
A function template defines an unbounded set of related functions.
|
| 6 |
|
| 7 |
[*Example 1*:
|
| 8 |
|
| 9 |
+
A family of sort functions can be declared like this:
|
| 10 |
|
| 11 |
``` cpp
|
| 12 |
template<class T> class Array { };
|
| 13 |
template<class T> void sort(Array<T>&);
|
| 14 |
```
|
| 15 |
|
| 16 |
— *end example*]
|
| 17 |
|
| 18 |
+
[*Note 1*: A function template can have the same name as other function
|
| 19 |
+
templates and non-template functions [[dcl.fct]] in the same
|
| 20 |
+
scope. — *end note*]
|
| 21 |
+
|
| 22 |
+
A non-template function is not related to a function template (i.e., it
|
| 23 |
+
is never considered to be a specialization), even if it has the same
|
| 24 |
+
name and type as a potentially generated function template
|
| 25 |
+
specialization.[^9]
|
| 26 |
|
| 27 |
#### Function template overloading <a id="temp.over.link">[[temp.over.link]]</a>
|
| 28 |
|
| 29 |
It is possible to overload function templates so that two different
|
| 30 |
function template specializations have the same type.
|
|
|
|
| 59 |
the relationship between the template parameters and the rest of the
|
| 60 |
signature.
|
| 61 |
|
| 62 |
[*Note 1*:
|
| 63 |
|
| 64 |
+
Two distinct function templates can have identical function return types
|
| 65 |
and function parameter lists, even if overload resolution alone cannot
|
| 66 |
distinguish them.
|
| 67 |
|
| 68 |
``` cpp
|
| 69 |
template<class T> void f();
|
| 70 |
+
template<int I> void f(); // OK, overloads the first template
|
| 71 |
// distinguishable with an explicit template argument list
|
| 72 |
```
|
| 73 |
|
| 74 |
— *end note*]
|
| 75 |
|
|
|
|
| 106 |
expression. Two unevaluated operands that do not involve template
|
| 107 |
parameters are considered equivalent if two function definitions
|
| 108 |
containing the expressions would satisfy the one-definition rule, except
|
| 109 |
that the tokens used to name types and declarations may differ as long
|
| 110 |
as they name the same entities, and the tokens used to form concept-ids
|
| 111 |
+
[[temp.names]] may differ as long as the two *template-id*s are the same
|
| 112 |
+
[[temp.type]].
|
| 113 |
|
| 114 |
[*Note 3*: For instance, `A<42>` and `A<40+2>` name the same
|
| 115 |
type. — *end note*]
|
| 116 |
|
| 117 |
Two *lambda-expression*s are never considered equivalent.
|
| 118 |
|
| 119 |
[*Note 4*: The intent is to avoid *lambda-expression*s appearing in the
|
| 120 |
signature of a function template with external linkage. — *end note*]
|
| 121 |
|
| 122 |
For determining whether two dependent names [[temp.dep]] are equivalent,
|
| 123 |
+
only the name itself is considered, not the result of name lookup.
|
| 124 |
+
|
| 125 |
+
[*Note 5*: If such a dependent name is unqualified, it is looked up
|
| 126 |
+
from the first declaration of the function template
|
| 127 |
+
[[temp.dep.candidate]]. — *end note*]
|
| 128 |
|
| 129 |
[*Example 3*:
|
| 130 |
|
| 131 |
``` cpp
|
| 132 |
template <int I, int J> void f(A<I+J>); // #1
|
|
|
|
| 135 |
template <class T> decltype(g(T())) h();
|
| 136 |
int g(int);
|
| 137 |
template <class T> decltype(g(T())) h() // redeclaration of h() uses the earlier lookup…
|
| 138 |
{ return g(T()); } // …{} although the lookup here does find g(int)
|
| 139 |
int i = h<int>(); // template argument substitution fails; g(int)
|
| 140 |
+
// not considered at the first declaration of h()
|
| 141 |
|
| 142 |
// ill-formed, no diagnostic required: the two expressions are functionally equivalent but not equivalent
|
| 143 |
template <int N> void foo(const char (*s)[([]{}, N)]);
|
| 144 |
template <int N> void foo(const char (*s)[([]{}, N)]);
|
| 145 |
|
|
|
|
| 156 |
same value. Two unevaluated operands that are not equivalent are
|
| 157 |
functionally equivalent if, for any given set of template arguments, the
|
| 158 |
expressions perform the same operations in the same order with the same
|
| 159 |
entities.
|
| 160 |
|
| 161 |
+
[*Note 6*: For instance, one could have redundant
|
| 162 |
parentheses. — *end note*]
|
| 163 |
|
| 164 |
+
[*Example 4*:
|
| 165 |
+
|
| 166 |
+
``` cpp
|
| 167 |
+
template<int I> concept C = true;
|
| 168 |
+
template<typename T> struct A {
|
| 169 |
+
void f() requires C<42>; // #1
|
| 170 |
+
void f() requires true; // OK, different functions
|
| 171 |
+
};
|
| 172 |
+
```
|
| 173 |
+
|
| 174 |
+
— *end example*]
|
| 175 |
+
|
| 176 |
Two *template-head*s are *equivalent* if their
|
| 177 |
*template-parameter-list*s have the same length, corresponding
|
| 178 |
*template-parameter*s are equivalent and are both declared with
|
| 179 |
*type-constraint*s that are equivalent if either *template-parameter* is
|
| 180 |
declared with a *type-constraint*, and if either *template-head* has a
|
|
|
|
| 194 |
rules above are used to compare expressions involving template
|
| 195 |
parameters. Two *template-head*s are *functionally equivalent* if they
|
| 196 |
accept and are satisfied by [[temp.constr.constr]] the same set of
|
| 197 |
template argument lists.
|
| 198 |
|
| 199 |
+
If the validity or meaning of the program depends on whether two
|
| 200 |
+
constructs are equivalent, and they are functionally equivalent but not
|
| 201 |
+
equivalent, the program is ill-formed, no diagnostic required.
|
| 202 |
+
Furthermore, if two function templates that do not correspond
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
|
| 204 |
+
- have the same name,
|
| 205 |
+
- have corresponding signatures [[basic.scope.scope]],
|
| 206 |
+
- would declare the same entity [[basic.link]] considering them to
|
| 207 |
+
correspond, and
|
| 208 |
+
- accept and are satisfied by the same set of template argument lists,
|
| 209 |
+
|
| 210 |
+
the program is ill-formed, no diagnostic required.
|
| 211 |
+
|
| 212 |
+
[*Note 7*:
|
| 213 |
|
| 214 |
This rule guarantees that equivalent declarations will be linked with
|
| 215 |
one another, while not requiring implementations to use heroic efforts
|
| 216 |
to guarantee that functionally equivalent declarations will be treated
|
| 217 |
as distinct. For example, the last two declarations are functionally
|
|
|
|
| 233 |
|
| 234 |
— *end note*]
|
| 235 |
|
| 236 |
#### Partial ordering of function templates <a id="temp.func.order">[[temp.func.order]]</a>
|
| 237 |
|
| 238 |
+
If multiple function templates share a name, the use of that name can be
|
| 239 |
+
ambiguous because template argument deduction [[temp.deduct]] may
|
| 240 |
+
identify a specialization for more than one function template. *Partial
|
| 241 |
+
ordering* of overloaded function template declarations is used in the
|
| 242 |
+
following contexts to select the function template to which a function
|
| 243 |
+
template specialization refers:
|
|
|
|
| 244 |
|
| 245 |
- during overload resolution for a call to a function template
|
| 246 |
specialization [[over.match.best]];
|
| 247 |
- when the address of a function template specialization is taken;
|
| 248 |
- when a placement operator delete that is a function template
|
| 249 |
+
specialization is selected to match a placement operator new
|
| 250 |
+
[[basic.stc.dynamic.deallocation]], [[expr.new]];
|
| 251 |
- when a friend function declaration [[temp.friend]], an explicit
|
| 252 |
instantiation [[temp.explicit]] or an explicit specialization
|
| 253 |
[[temp.expl.spec]] refers to a function template specialization.
|
| 254 |
|
| 255 |
Partial ordering selects which of two function templates is more
|
|
|
|
| 399 |
template<class T > void f(T); // #2
|
| 400 |
template<class T, class... U> void g(T*, U...); // #3
|
| 401 |
template<class T > void g(T); // #4
|
| 402 |
|
| 403 |
void h(int i) {
|
| 404 |
+
f(&i); // OK, calls #2
|
| 405 |
+
g(&i); // OK, calls #3
|
| 406 |
}
|
| 407 |
```
|
| 408 |
|
| 409 |
— *end example*]
|
| 410 |
|
|
|
|
| 454 |
|
| 455 |
void f(C auto &, auto &) = delete;
|
| 456 |
template <C Q> void f(Q &, C auto &);
|
| 457 |
|
| 458 |
void g(struct A *ap, struct B *bp) {
|
| 459 |
+
f(*ap, *bp); // OK, can use different methods to produce template parameters
|
| 460 |
}
|
| 461 |
|
| 462 |
template <typename T, typename U> struct X {};
|
| 463 |
|
| 464 |
template <typename T, C U, typename V> bool operator==(X<T, U>, V) = delete;
|
| 465 |
template <C T, C U, C V> bool operator==(T, X<U, V>);
|
| 466 |
|
| 467 |
void h() {
|
| 468 |
+
X<void *, int>{} == 0; // OK, correspondence of [T, U, V] and [U, V, T]
|
| 469 |
}
|
| 470 |
```
|
| 471 |
|
| 472 |
— *end example*]
|
| 473 |
|