tmp/tmpvrrxzkr1/{from.md → to.md}
RENAMED
|
@@ -172,22 +172,24 @@ shall be one of:
|
|
| 172 |
- for a non-type *template-parameter* of integral or enumeration type, a
|
| 173 |
converted constant expression ([[expr.const]]) of the type of the
|
| 174 |
*template-parameter*; or
|
| 175 |
- the name of a non-type *template-parameter*; or
|
| 176 |
- a constant expression ([[expr.const]]) that designates the address of
|
| 177 |
-
|
| 178 |
-
linkage or a function with external or internal linkage,
|
| 179 |
-
function templates and function *template-id*s but excluding
|
| 180 |
non-static class members, expressed (ignoring parentheses) as `&`
|
| 181 |
-
*id-expression*,
|
| 182 |
-
|
|
|
|
| 183 |
*template-parameter* is a reference; or
|
| 184 |
- a constant expression that evaluates to a null pointer value (
|
| 185 |
[[conv.ptr]]); or
|
| 186 |
- a constant expression that evaluates to a null member pointer value (
|
| 187 |
[[conv.mem]]); or
|
| 188 |
-
- a pointer to member expressed as described in [[expr.unary.op]]
|
|
|
|
| 189 |
|
| 190 |
A string literal ([[lex.string]]) does not satisfy the requirements of
|
| 191 |
any of these categories and thus is not an acceptable
|
| 192 |
*template-argument*.
|
| 193 |
|
|
@@ -241,18 +243,17 @@ the program is ill-formed.
|
|
| 241 |
- for a non-type *template-parameter* of type pointer to object,
|
| 242 |
qualification conversions ([[conv.qual]]) and the array-to-pointer
|
| 243 |
conversion ([[conv.array]]) are applied; if the *template-argument*
|
| 244 |
is of type `std::nullptr_t`, the null pointer conversion (
|
| 245 |
[[conv.ptr]]) is applied. In particular, neither the null pointer
|
| 246 |
-
conversion for a zero-valued
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
*template-
|
| 251 |
-
|
| 252 |
-
*template-
|
| 253 |
-
“pointer to int.”
|
| 254 |
- For a non-type *template-parameter* of type reference to object, no
|
| 255 |
conversions apply. The type referred to by the reference may be more
|
| 256 |
cv-qualified than the (otherwise identical) type of the
|
| 257 |
*template-argument*. The *template-parameter* is bound directly to the
|
| 258 |
*template-argument*, which shall be an lvalue.
|
|
@@ -308,15 +309,15 @@ only primary class templates are considered when matching the template
|
|
| 308 |
template argument with the corresponding parameter; partial
|
| 309 |
specializations are not considered even if their parameter lists match
|
| 310 |
that of the template template parameter.
|
| 311 |
|
| 312 |
Any partial specializations ([[temp.class.spec]]) associated with the
|
| 313 |
-
primary class template
|
| 314 |
-
template *template-parameter* is
|
| 315 |
-
not visible at the point of
|
| 316 |
-
selected had it been visible, the
|
| 317 |
-
is required.
|
| 318 |
|
| 319 |
``` cpp
|
| 320 |
template<class T> class A { // primary template
|
| 321 |
int x;
|
| 322 |
};
|
|
@@ -331,10 +332,26 @@ C<A> c; // V<int> within C<A> uses the primary template,
|
|
| 331 |
// so c.y.x has type int
|
| 332 |
// V<int*> within C<A> uses the partial specialization,
|
| 333 |
// so c.z.x has type long
|
| 334 |
```
|
| 335 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 336 |
``` cpp
|
| 337 |
template<class T> class A { /* ... */ };
|
| 338 |
template<class T, class U = T> class B { /* ... */ };
|
| 339 |
template <class ... Types> class C { /* ... */ };
|
| 340 |
|
|
@@ -348,22 +365,10 @@ X<C> xc; // ill-formed: a template parameter pack does not match a te
|
|
| 348 |
Y<A> ya; // OK
|
| 349 |
Y<B> yb; // OK
|
| 350 |
Y<C> yc; // OK
|
| 351 |
```
|
| 352 |
|
| 353 |
-
A *template-argument* matches a template *template-parameter* (call it
|
| 354 |
-
`P`) when each of the template parameters in the
|
| 355 |
-
*template-parameter-list* of the *template-argument*’s corresponding
|
| 356 |
-
class template or alias template (call it `A`) matches the corresponding
|
| 357 |
-
template parameter in the *template-parameter-list* of `P`. When `P`’s
|
| 358 |
-
*template-parameter-list* contains a template parameter pack (
|
| 359 |
-
[[temp.variadic]]), the template parameter pack will match zero or more
|
| 360 |
-
template parameters or template parameter packs in the
|
| 361 |
-
*template-parameter-list* of `A` with the same type and form as the
|
| 362 |
-
template parameter pack in `P` (ignoring whether those template
|
| 363 |
-
parameters are template parameter packs)
|
| 364 |
-
|
| 365 |
``` cpp
|
| 366 |
template <class T> struct eval;
|
| 367 |
|
| 368 |
template <template <class, class...> class TT, class T1, class... Rest>
|
| 369 |
struct eval<TT<T1, Rest...>> { };
|
|
|
|
| 172 |
- for a non-type *template-parameter* of integral or enumeration type, a
|
| 173 |
converted constant expression ([[expr.const]]) of the type of the
|
| 174 |
*template-parameter*; or
|
| 175 |
- the name of a non-type *template-parameter*; or
|
| 176 |
- a constant expression ([[expr.const]]) that designates the address of
|
| 177 |
+
a complete object with static storage duration and external or
|
| 178 |
+
internal linkage or a function with external or internal linkage,
|
| 179 |
+
including function templates and function *template-id*s but excluding
|
| 180 |
non-static class members, expressed (ignoring parentheses) as `&`
|
| 181 |
+
*id-expression*, where the *id-expression* is the name of an object or
|
| 182 |
+
function, except that the `&` may be omitted if the name refers to a
|
| 183 |
+
function or array and shall be omitted if the corresponding
|
| 184 |
*template-parameter* is a reference; or
|
| 185 |
- a constant expression that evaluates to a null pointer value (
|
| 186 |
[[conv.ptr]]); or
|
| 187 |
- a constant expression that evaluates to a null member pointer value (
|
| 188 |
[[conv.mem]]); or
|
| 189 |
+
- a pointer to member expressed as described in [[expr.unary.op]]; or
|
| 190 |
+
- a constant expression of type `std::nullptr_t`.
|
| 191 |
|
| 192 |
A string literal ([[lex.string]]) does not satisfy the requirements of
|
| 193 |
any of these categories and thus is not an acceptable
|
| 194 |
*template-argument*.
|
| 195 |
|
|
|
|
| 243 |
- for a non-type *template-parameter* of type pointer to object,
|
| 244 |
qualification conversions ([[conv.qual]]) and the array-to-pointer
|
| 245 |
conversion ([[conv.array]]) are applied; if the *template-argument*
|
| 246 |
is of type `std::nullptr_t`, the null pointer conversion (
|
| 247 |
[[conv.ptr]]) is applied. In particular, neither the null pointer
|
| 248 |
+
conversion for a zero-valued integer literal ([[conv.ptr]]) nor the
|
| 249 |
+
derived-to-base conversion ([[conv.ptr]]) are applied. Although `0`
|
| 250 |
+
is a valid *template-argument* for a non-type *template-parameter* of
|
| 251 |
+
integral type, it is not a valid *template-argument* for a non-type
|
| 252 |
+
*template-parameter* of pointer type. However, both `(int*)0` and
|
| 253 |
+
`nullptr` are valid *template-argument*s for a non-type
|
| 254 |
+
*template-parameter* of type “pointer to int.”
|
|
|
|
| 255 |
- For a non-type *template-parameter* of type reference to object, no
|
| 256 |
conversions apply. The type referred to by the reference may be more
|
| 257 |
cv-qualified than the (otherwise identical) type of the
|
| 258 |
*template-argument*. The *template-parameter* is bound directly to the
|
| 259 |
*template-argument*, which shall be an lvalue.
|
|
|
|
| 309 |
template argument with the corresponding parameter; partial
|
| 310 |
specializations are not considered even if their parameter lists match
|
| 311 |
that of the template template parameter.
|
| 312 |
|
| 313 |
Any partial specializations ([[temp.class.spec]]) associated with the
|
| 314 |
+
primary class template or primary variable template are considered when
|
| 315 |
+
a specialization based on the template *template-parameter* is
|
| 316 |
+
instantiated. If a specialization is not visible at the point of
|
| 317 |
+
instantiation, and it would have been selected had it been visible, the
|
| 318 |
+
program is ill-formed; no diagnostic is required.
|
| 319 |
|
| 320 |
``` cpp
|
| 321 |
template<class T> class A { // primary template
|
| 322 |
int x;
|
| 323 |
};
|
|
|
|
| 332 |
// so c.y.x has type int
|
| 333 |
// V<int*> within C<A> uses the partial specialization,
|
| 334 |
// so c.z.x has type long
|
| 335 |
```
|
| 336 |
|
| 337 |
+
A *template-argument* matches a template *template-parameter* (call it
|
| 338 |
+
`P`) when each of the template parameters in the
|
| 339 |
+
*template-parameter-list* of the *template-argument*’s corresponding
|
| 340 |
+
class template or alias template (call it `A`) matches the corresponding
|
| 341 |
+
template parameter in the *template-parameter-list* of `P`. Two template
|
| 342 |
+
parameters match if they are of the same kind (type, non-type,
|
| 343 |
+
template), for non-type *template-parameter*s, their types are
|
| 344 |
+
equivalent ([[temp.over.link]]), and for template
|
| 345 |
+
*template-parameter*s, each of their corresponding *template-parameter*s
|
| 346 |
+
matches, recursively. When `P`’s *template-parameter-list* contains a
|
| 347 |
+
template parameter pack ([[temp.variadic]]), the template parameter
|
| 348 |
+
pack will match zero or more template parameters or template parameter
|
| 349 |
+
packs in the *template-parameter-list* of `A` with the same type and
|
| 350 |
+
form as the template parameter pack in `P` (ignoring whether those
|
| 351 |
+
template parameters are template parameter packs).
|
| 352 |
+
|
| 353 |
``` cpp
|
| 354 |
template<class T> class A { /* ... */ };
|
| 355 |
template<class T, class U = T> class B { /* ... */ };
|
| 356 |
template <class ... Types> class C { /* ... */ };
|
| 357 |
|
|
|
|
| 365 |
Y<A> ya; // OK
|
| 366 |
Y<B> yb; // OK
|
| 367 |
Y<C> yc; // OK
|
| 368 |
```
|
| 369 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
``` cpp
|
| 371 |
template <class T> struct eval;
|
| 372 |
|
| 373 |
template <template <class, class...> class TT, class T1, class... Rest>
|
| 374 |
struct eval<TT<T1, Rest...>> { };
|