- tmp/tmp3zz89g2c/{from.md → to.md} +199 -150
tmp/tmp3zz89g2c/{from.md → to.md}
RENAMED
|
@@ -7,10 +7,12 @@ match the type and form specified for the corresponding parameter
|
|
| 7 |
declared by the template in its *template-parameter-list*. When the
|
| 8 |
parameter declared by the template is a template parameter pack (
|
| 9 |
[[temp.variadic]]), it will correspond to zero or more
|
| 10 |
*template-argument*s.
|
| 11 |
|
|
|
|
|
|
|
| 12 |
``` cpp
|
| 13 |
template<class T> class Array {
|
| 14 |
T* v;
|
| 15 |
int sz;
|
| 16 |
public:
|
|
@@ -18,119 +20,159 @@ public:
|
|
| 18 |
T& operator[](int);
|
| 19 |
T& elem(int i) { return v[i]; }
|
| 20 |
};
|
| 21 |
|
| 22 |
Array<int> v1(20);
|
| 23 |
-
typedef std::complex<double> dcomplex; // std::complex is a standard
|
| 24 |
-
// library template
|
| 25 |
Array<dcomplex> v2(30);
|
| 26 |
Array<dcomplex> v3(40);
|
| 27 |
|
| 28 |
void bar() {
|
| 29 |
v1[3] = 7;
|
| 30 |
v2[3] = v3.elem(4) = dcomplex(7,8);
|
| 31 |
}
|
| 32 |
```
|
| 33 |
|
|
|
|
|
|
|
| 34 |
In a *template-argument*, an ambiguity between a *type-id* and an
|
| 35 |
expression is resolved to a *type-id*, regardless of the form of the
|
| 36 |
corresponding *template-parameter*.[^3]
|
| 37 |
|
|
|
|
|
|
|
| 38 |
``` cpp
|
| 39 |
template<class T> void f();
|
| 40 |
template<int I> void f();
|
| 41 |
|
| 42 |
void g() {
|
| 43 |
f<int()>(); // int() is a type-id: call the first f()
|
| 44 |
}
|
| 45 |
```
|
| 46 |
|
|
|
|
|
|
|
| 47 |
The name of a *template-argument* shall be accessible at the point where
|
| 48 |
-
it is used as a *template-argument*.
|
| 49 |
-
|
| 50 |
-
*
|
| 51 |
-
|
| 52 |
-
|
|
|
|
|
|
|
|
|
|
| 53 |
|
| 54 |
``` cpp
|
| 55 |
template<class T> class X {
|
| 56 |
static T t;
|
| 57 |
};
|
| 58 |
|
| 59 |
class Y {
|
| 60 |
private:
|
| 61 |
-
struct S {
|
| 62 |
X<S> x; // OK: S is accessible
|
| 63 |
// X<Y::S> has a static member of type Y::S
|
| 64 |
// OK: even though Y::S is private
|
| 65 |
};
|
| 66 |
|
| 67 |
X<Y::S> y; // error: S not accessible
|
| 68 |
```
|
| 69 |
|
|
|
|
|
|
|
| 70 |
For a *template-argument* that is a class type or a class template, the
|
| 71 |
template definition has no special access rights to the members of the
|
| 72 |
*template-argument*.
|
| 73 |
|
|
|
|
|
|
|
| 74 |
``` cpp
|
| 75 |
template <template <class TT> class T> class A {
|
| 76 |
typename T<int>::S s;
|
| 77 |
};
|
| 78 |
|
| 79 |
template <class U> class B {
|
| 80 |
private:
|
| 81 |
-
struct S {
|
| 82 |
};
|
| 83 |
|
| 84 |
A<B> b; // ill-formed: A has no access to B::S
|
| 85 |
```
|
| 86 |
|
|
|
|
|
|
|
| 87 |
When template argument packs or default *template-argument*s are used, a
|
| 88 |
*template-argument* list can be empty. In that case the empty `<>`
|
| 89 |
-
brackets shall still be used as the *template-argument-list
|
|
|
|
|
|
|
| 90 |
|
| 91 |
``` cpp
|
| 92 |
template<class T = char> class String;
|
| 93 |
String<>* p; // OK: String<char>
|
| 94 |
String* q; // syntax error
|
| 95 |
template<class ... Elements> class Tuple;
|
| 96 |
Tuple<>* t; // OK: Elements is empty
|
| 97 |
Tuple* u; // syntax error
|
| 98 |
```
|
| 99 |
|
|
|
|
|
|
|
| 100 |
An explicit destructor call ([[class.dtor]]) for an object that has a
|
| 101 |
type that is a class template specialization may explicitly specify the
|
| 102 |
*template-argument*s.
|
| 103 |
|
|
|
|
|
|
|
| 104 |
``` cpp
|
| 105 |
template<class T> struct A {
|
| 106 |
~A();
|
| 107 |
};
|
| 108 |
void f(A<int>* p, A<int>* q) {
|
| 109 |
p->A<int>::~A(); // OK: destructor call
|
| 110 |
q->A<int>::~A<int>(); // OK: destructor call
|
| 111 |
}
|
| 112 |
```
|
| 113 |
|
|
|
|
|
|
|
| 114 |
If the use of a *template-argument* gives rise to an ill-formed
|
| 115 |
construct in the instantiation of a template specialization, the program
|
| 116 |
is ill-formed.
|
| 117 |
|
| 118 |
When the template in a *template-id* is an overloaded function template,
|
| 119 |
both non-template functions in the overload set and function templates
|
| 120 |
in the overload set for which the *template-argument*s do not match the
|
| 121 |
*template-parameter*s are ignored. If none of the function templates
|
| 122 |
have matching *template-parameter*s, the program is ill-formed.
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
A *template-argument* followed by an ellipsis is a pack expansion (
|
| 125 |
[[temp.variadic]]).
|
| 126 |
|
| 127 |
### Template type arguments <a id="temp.arg.type">[[temp.arg.type]]</a>
|
| 128 |
|
| 129 |
A *template-argument* for a *template-parameter* which is a type shall
|
| 130 |
be a *type-id*.
|
| 131 |
|
|
|
|
|
|
|
| 132 |
``` cpp
|
| 133 |
template <class T> class X { };
|
| 134 |
template <class T> void f(T t) { }
|
| 135 |
struct { } unnamed_obj;
|
| 136 |
|
|
@@ -146,161 +188,135 @@ void f() {
|
|
| 146 |
f(unnamed_obj); // OK
|
| 147 |
f(b); // OK
|
| 148 |
}
|
| 149 |
```
|
| 150 |
|
| 151 |
-
|
| 152 |
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
syntactic form of a function declarator to have function type, the
|
| 156 |
-
program is ill-formed.
|
| 157 |
-
|
| 158 |
-
``` cpp
|
| 159 |
-
template<class T> struct A {
|
| 160 |
-
static T t;
|
| 161 |
-
};
|
| 162 |
-
typedef int function();
|
| 163 |
-
A<function> a; // ill-formed: would declare A<function>::t
|
| 164 |
-
// as a static member function
|
| 165 |
-
```
|
| 166 |
|
| 167 |
### Template non-type arguments <a id="temp.arg.nontype">[[temp.arg.nontype]]</a>
|
| 168 |
|
| 169 |
-
|
| 170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
|
| 172 |
-
- for a non-type *template-parameter*
|
| 173 |
converted constant expression ([[expr.const]]) of the type of the
|
| 174 |
-
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
*template-argument*.
|
| 195 |
|
|
|
|
|
|
|
| 196 |
``` cpp
|
| 197 |
template<class T, const char* p> class X {
|
| 198 |
-
|
| 199 |
};
|
| 200 |
|
| 201 |
X<int, "Studebaker"> x1; // error: string literal as template-argument
|
| 202 |
|
| 203 |
const char p[] = "Vivisectionist";
|
| 204 |
X<int,p> x2; // OK
|
| 205 |
```
|
| 206 |
|
| 207 |
-
|
| 208 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
|
| 210 |
``` cpp
|
| 211 |
template<int* p> class X { };
|
| 212 |
|
| 213 |
int a[10];
|
| 214 |
struct S { int m; static int s; } s;
|
| 215 |
|
| 216 |
X<&a[2]> x3; // error: address of array element
|
| 217 |
X<&s.m> x4; // error: address of non-static member
|
| 218 |
-
X<&s.s> x5; //
|
| 219 |
X<&S::s> x6; // OK: address of static member
|
| 220 |
```
|
| 221 |
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
|
| 226 |
``` cpp
|
| 227 |
-
template<const int& CRI> struct B {
|
| 228 |
|
| 229 |
B<1> b2; // error: temporary would be required for template argument
|
| 230 |
|
| 231 |
int c = 1;
|
| 232 |
B<c> b1; // OK
|
| 233 |
```
|
| 234 |
|
| 235 |
-
|
| 236 |
-
non-type *template-argument*. If a non-type *template-argument* cannot
|
| 237 |
-
be converted to the type of the corresponding *template-parameter* then
|
| 238 |
-
the program is ill-formed.
|
| 239 |
|
| 240 |
-
|
| 241 |
-
conversions permitted in a converted constant expression (
|
| 242 |
-
[[expr.const]]) are applied.
|
| 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.
|
| 260 |
-
- For a non-type *template-parameter* of type pointer to function, the
|
| 261 |
-
function-to-pointer conversion ([[conv.func]]) is applied; if the
|
| 262 |
-
*template-argument* is of type `std::nullptr_t`, the null pointer
|
| 263 |
-
conversion ([[conv.ptr]]) is applied. If the *template-argument*
|
| 264 |
-
represents a set of overloaded functions (or a pointer to such), the
|
| 265 |
-
matching function is selected from the set ([[over.over]]).
|
| 266 |
-
- For a non-type *template-parameter* of type reference to function, no
|
| 267 |
-
conversions apply. If the *template-argument* represents a set of
|
| 268 |
-
overloaded functions, the matching function is selected from the set (
|
| 269 |
-
[[over.over]]).
|
| 270 |
-
- For a non-type *template-parameter* of type pointer to member
|
| 271 |
-
function, if the *template-argument* is of type `std::nullptr_t`, the
|
| 272 |
-
null member pointer conversion ([[conv.mem]]) is applied; otherwise,
|
| 273 |
-
no conversions apply. If the *template-argument* represents a set of
|
| 274 |
-
overloaded member functions, the matching member function is selected
|
| 275 |
-
from the set ([[over.over]]).
|
| 276 |
-
- For a non-type *template-parameter* of type pointer to data member,
|
| 277 |
-
qualification conversions ([[conv.qual]]) are applied; if the
|
| 278 |
-
*template-argument* is of type `std::nullptr_t`, the null member
|
| 279 |
-
pointer conversion ([[conv.mem]]) is applied.
|
| 280 |
-
|
| 281 |
-
``` cpp
|
| 282 |
-
template<const int* pci> struct X { /* ... */ };
|
| 283 |
-
int ai[10];
|
| 284 |
-
X<ai> xi; // array to pointer and qualification conversions
|
| 285 |
-
|
| 286 |
-
struct Y { /* ... */ };
|
| 287 |
-
template<const Y& b> struct Z { /* ... */ };
|
| 288 |
-
Y y;
|
| 289 |
-
Z<y> z; // no conversion, but note extra cv-qualification
|
| 290 |
-
|
| 291 |
-
template<int (&pa)[5]> struct W { /* ... */ };
|
| 292 |
-
int b[5];
|
| 293 |
-
W<b> w; // no conversion
|
| 294 |
-
|
| 295 |
-
void f(char);
|
| 296 |
-
void f(int);
|
| 297 |
-
|
| 298 |
-
template<void (*pf)(int)> struct A { /* ... */ };
|
| 299 |
-
|
| 300 |
-
A<&f> a; // selects f(int)
|
| 301 |
-
```
|
| 302 |
|
| 303 |
### Template template arguments <a id="temp.arg.template">[[temp.arg.template]]</a>
|
| 304 |
|
| 305 |
A *template-argument* for a template *template-parameter* shall be the
|
| 306 |
name of a class template or an alias template, expressed as
|
|
@@ -313,11 +329,13 @@ that of the template template parameter.
|
|
| 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
|
|
|
|
|
|
|
| 319 |
|
| 320 |
``` cpp
|
| 321 |
template<class T> class A { // primary template
|
| 322 |
int x;
|
| 323 |
};
|
|
@@ -326,49 +344,56 @@ template<class T> class A<T*> { // partial specialization
|
|
| 326 |
};
|
| 327 |
template<template<class U> class V> class C {
|
| 328 |
V<int> y;
|
| 329 |
V<int*> z;
|
| 330 |
};
|
| 331 |
-
C<A> c;
|
| 332 |
-
|
| 333 |
-
// V<int*> within C<A> uses the partial specialization,
|
| 334 |
-
// so c.z.x has type long
|
| 335 |
```
|
| 336 |
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
*template-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
parameters
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
*template-parameter*s,
|
| 346 |
-
|
| 347 |
-
template
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
template
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
|
| 353 |
``` cpp
|
| 354 |
-
template<class T> class A {
|
| 355 |
-
template<class T, class U = T> class B {
|
| 356 |
-
template
|
| 357 |
-
|
| 358 |
-
template<template<class> class P> class X {
|
| 359 |
-
template<template<class ...> class Q> class Y {
|
|
|
|
| 360 |
|
| 361 |
X<A> xa; // OK
|
| 362 |
-
X<B> xb; //
|
| 363 |
-
X<C> xc; //
|
| 364 |
-
|
| 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...>> { };
|
|
@@ -384,5 +409,29 @@ eval<B<int, float>> eB; // OK: matches partial specialization of eval
|
|
| 384 |
eval<C<17>> eC; // error: C does not match TT in partial specialization
|
| 385 |
eval<D<int, 17>> eD; // error: D does not match TT in partial specialization
|
| 386 |
eval<E<int, float>> eE; // error: E does not match TT in partial specialization
|
| 387 |
```
|
| 388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
declared by the template in its *template-parameter-list*. When the
|
| 8 |
parameter declared by the template is a template parameter pack (
|
| 9 |
[[temp.variadic]]), it will correspond to zero or more
|
| 10 |
*template-argument*s.
|
| 11 |
|
| 12 |
+
[*Example 1*:
|
| 13 |
+
|
| 14 |
``` cpp
|
| 15 |
template<class T> class Array {
|
| 16 |
T* v;
|
| 17 |
int sz;
|
| 18 |
public:
|
|
|
|
| 20 |
T& operator[](int);
|
| 21 |
T& elem(int i) { return v[i]; }
|
| 22 |
};
|
| 23 |
|
| 24 |
Array<int> v1(20);
|
| 25 |
+
typedef std::complex<double> dcomplex; // std::complex is a standard library template
|
|
|
|
| 26 |
Array<dcomplex> v2(30);
|
| 27 |
Array<dcomplex> v3(40);
|
| 28 |
|
| 29 |
void bar() {
|
| 30 |
v1[3] = 7;
|
| 31 |
v2[3] = v3.elem(4) = dcomplex(7,8);
|
| 32 |
}
|
| 33 |
```
|
| 34 |
|
| 35 |
+
— *end example*]
|
| 36 |
+
|
| 37 |
In a *template-argument*, an ambiguity between a *type-id* and an
|
| 38 |
expression is resolved to a *type-id*, regardless of the form of the
|
| 39 |
corresponding *template-parameter*.[^3]
|
| 40 |
|
| 41 |
+
[*Example 2*:
|
| 42 |
+
|
| 43 |
``` cpp
|
| 44 |
template<class T> void f();
|
| 45 |
template<int I> void f();
|
| 46 |
|
| 47 |
void g() {
|
| 48 |
f<int()>(); // int() is a type-id: call the first f()
|
| 49 |
}
|
| 50 |
```
|
| 51 |
|
| 52 |
+
— *end example*]
|
| 53 |
+
|
| 54 |
The name of a *template-argument* shall be accessible at the point where
|
| 55 |
+
it is used as a *template-argument*.
|
| 56 |
+
|
| 57 |
+
[*Note 1*: If the name of the *template-argument* is accessible at the
|
| 58 |
+
point where it is used as a *template-argument*, there is no further
|
| 59 |
+
access restriction in the resulting instantiation where the
|
| 60 |
+
corresponding *template-parameter* name is used. — *end note*]
|
| 61 |
+
|
| 62 |
+
[*Example 3*:
|
| 63 |
|
| 64 |
``` cpp
|
| 65 |
template<class T> class X {
|
| 66 |
static T t;
|
| 67 |
};
|
| 68 |
|
| 69 |
class Y {
|
| 70 |
private:
|
| 71 |
+
struct S { ... };
|
| 72 |
X<S> x; // OK: S is accessible
|
| 73 |
// X<Y::S> has a static member of type Y::S
|
| 74 |
// OK: even though Y::S is private
|
| 75 |
};
|
| 76 |
|
| 77 |
X<Y::S> y; // error: S not accessible
|
| 78 |
```
|
| 79 |
|
| 80 |
+
— *end example*]
|
| 81 |
+
|
| 82 |
For a *template-argument* that is a class type or a class template, the
|
| 83 |
template definition has no special access rights to the members of the
|
| 84 |
*template-argument*.
|
| 85 |
|
| 86 |
+
[*Example 4*:
|
| 87 |
+
|
| 88 |
``` cpp
|
| 89 |
template <template <class TT> class T> class A {
|
| 90 |
typename T<int>::S s;
|
| 91 |
};
|
| 92 |
|
| 93 |
template <class U> class B {
|
| 94 |
private:
|
| 95 |
+
struct S { ... };
|
| 96 |
};
|
| 97 |
|
| 98 |
A<B> b; // ill-formed: A has no access to B::S
|
| 99 |
```
|
| 100 |
|
| 101 |
+
— *end example*]
|
| 102 |
+
|
| 103 |
When template argument packs or default *template-argument*s are used, a
|
| 104 |
*template-argument* list can be empty. In that case the empty `<>`
|
| 105 |
+
brackets shall still be used as the *template-argument-list*.
|
| 106 |
+
|
| 107 |
+
[*Example 5*:
|
| 108 |
|
| 109 |
``` cpp
|
| 110 |
template<class T = char> class String;
|
| 111 |
String<>* p; // OK: String<char>
|
| 112 |
String* q; // syntax error
|
| 113 |
template<class ... Elements> class Tuple;
|
| 114 |
Tuple<>* t; // OK: Elements is empty
|
| 115 |
Tuple* u; // syntax error
|
| 116 |
```
|
| 117 |
|
| 118 |
+
— *end example*]
|
| 119 |
+
|
| 120 |
An explicit destructor call ([[class.dtor]]) for an object that has a
|
| 121 |
type that is a class template specialization may explicitly specify the
|
| 122 |
*template-argument*s.
|
| 123 |
|
| 124 |
+
[*Example 6*:
|
| 125 |
+
|
| 126 |
``` cpp
|
| 127 |
template<class T> struct A {
|
| 128 |
~A();
|
| 129 |
};
|
| 130 |
void f(A<int>* p, A<int>* q) {
|
| 131 |
p->A<int>::~A(); // OK: destructor call
|
| 132 |
q->A<int>::~A<int>(); // OK: destructor call
|
| 133 |
}
|
| 134 |
```
|
| 135 |
|
| 136 |
+
— *end example*]
|
| 137 |
+
|
| 138 |
If the use of a *template-argument* gives rise to an ill-formed
|
| 139 |
construct in the instantiation of a template specialization, the program
|
| 140 |
is ill-formed.
|
| 141 |
|
| 142 |
When the template in a *template-id* is an overloaded function template,
|
| 143 |
both non-template functions in the overload set and function templates
|
| 144 |
in the overload set for which the *template-argument*s do not match the
|
| 145 |
*template-parameter*s are ignored. If none of the function templates
|
| 146 |
have matching *template-parameter*s, the program is ill-formed.
|
| 147 |
|
| 148 |
+
When a *simple-template-id* does not name a function, a default
|
| 149 |
+
*template-argument* is implicitly instantiated ([[temp.inst]]) when the
|
| 150 |
+
value of that default argument is needed.
|
| 151 |
+
|
| 152 |
+
[*Example 7*:
|
| 153 |
+
|
| 154 |
+
``` cpp
|
| 155 |
+
template<typename T, typename U = int> struct S { };
|
| 156 |
+
S<bool>* p; // the type of p is S<bool, int>*
|
| 157 |
+
```
|
| 158 |
+
|
| 159 |
+
The default argument for `U` is instantiated to form the type
|
| 160 |
+
`S<bool, int>*`.
|
| 161 |
+
|
| 162 |
+
— *end example*]
|
| 163 |
+
|
| 164 |
A *template-argument* followed by an ellipsis is a pack expansion (
|
| 165 |
[[temp.variadic]]).
|
| 166 |
|
| 167 |
### Template type arguments <a id="temp.arg.type">[[temp.arg.type]]</a>
|
| 168 |
|
| 169 |
A *template-argument* for a *template-parameter* which is a type shall
|
| 170 |
be a *type-id*.
|
| 171 |
|
| 172 |
+
[*Example 1*:
|
| 173 |
+
|
| 174 |
``` cpp
|
| 175 |
template <class T> class X { };
|
| 176 |
template <class T> void f(T t) { }
|
| 177 |
struct { } unnamed_obj;
|
| 178 |
|
|
|
|
| 188 |
f(unnamed_obj); // OK
|
| 189 |
f(b); // OK
|
| 190 |
}
|
| 191 |
```
|
| 192 |
|
| 193 |
+
— *end example*]
|
| 194 |
|
| 195 |
+
[*Note 1*: A template type argument may be an incomplete type (
|
| 196 |
+
[[basic.types]]). — *end note*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
|
| 198 |
### Template non-type arguments <a id="temp.arg.nontype">[[temp.arg.nontype]]</a>
|
| 199 |
|
| 200 |
+
If the type of a *template-parameter* contains a placeholder type (
|
| 201 |
+
[[dcl.spec.auto]], [[temp.param]]), the deduced parameter type is
|
| 202 |
+
determined from the type of the *template-argument* by placeholder type
|
| 203 |
+
deduction ([[dcl.type.auto.deduct]]). If a deduced parameter type is
|
| 204 |
+
not permitted for a *template-parameter* declaration ([[temp.param]]),
|
| 205 |
+
the program is ill-formed.
|
| 206 |
|
| 207 |
+
A *template-argument* for a non-type *template-parameter* shall be a
|
| 208 |
converted constant expression ([[expr.const]]) of the type of the
|
| 209 |
+
*template-parameter*. For a non-type *template-parameter* of reference
|
| 210 |
+
or pointer type, the value of the constant expression shall not refer to
|
| 211 |
+
(or for a pointer type, shall not be the address of):
|
| 212 |
+
|
| 213 |
+
- a subobject ([[intro.object]]),
|
| 214 |
+
- a temporary object ([[class.temporary]]),
|
| 215 |
+
- a string literal ([[lex.string]]),
|
| 216 |
+
- the result of a `typeid` expression ([[expr.typeid]]), or
|
| 217 |
+
- a predefined `__func__` variable ([[dcl.fct.def.general]]).
|
| 218 |
+
|
| 219 |
+
[*Note 1*: If the *template-argument* represents a set of overloaded
|
| 220 |
+
functions (or a pointer or member pointer to such), the matching
|
| 221 |
+
function is selected from the set ([[over.over]]). — *end note*]
|
| 222 |
+
|
| 223 |
+
[*Example 1*:
|
| 224 |
+
|
| 225 |
+
``` cpp
|
| 226 |
+
template<const int* pci> struct X { ... };
|
| 227 |
+
int ai[10];
|
| 228 |
+
X<ai> xi; // array to pointer and qualification conversions
|
| 229 |
+
|
| 230 |
+
struct Y { ... };
|
| 231 |
+
template<const Y& b> struct Z { ... };
|
| 232 |
+
Y y;
|
| 233 |
+
Z<y> z; // no conversion, but note extra cv-qualification
|
| 234 |
+
|
| 235 |
+
template<int (&pa)[5]> struct W { ... };
|
| 236 |
+
int b[5];
|
| 237 |
+
W<b> w; // no conversion
|
| 238 |
+
|
| 239 |
+
void f(char);
|
| 240 |
+
void f(int);
|
| 241 |
+
|
| 242 |
+
template<void (*pf)(int)> struct A { ... };
|
| 243 |
+
|
| 244 |
+
A<&f> a; // selects f(int)
|
| 245 |
+
|
| 246 |
+
template<auto n> struct B { ... };
|
| 247 |
+
B<5> b1; // OK: template parameter type is int
|
| 248 |
+
B<'a'> b2; // OK: template parameter type is char
|
| 249 |
+
B<2.5> b3; // error: template parameter type cannot be double
|
| 250 |
+
```
|
| 251 |
+
|
| 252 |
+
— *end example*]
|
| 253 |
+
|
| 254 |
+
[*Note 2*:
|
| 255 |
+
|
| 256 |
+
A string literal ([[lex.string]]) is not an acceptable
|
| 257 |
*template-argument*.
|
| 258 |
|
| 259 |
+
[*Example 2*:
|
| 260 |
+
|
| 261 |
``` cpp
|
| 262 |
template<class T, const char* p> class X {
|
| 263 |
+
...
|
| 264 |
};
|
| 265 |
|
| 266 |
X<int, "Studebaker"> x1; // error: string literal as template-argument
|
| 267 |
|
| 268 |
const char p[] = "Vivisectionist";
|
| 269 |
X<int,p> x2; // OK
|
| 270 |
```
|
| 271 |
|
| 272 |
+
— *end example*]
|
| 273 |
+
|
| 274 |
+
— *end note*]
|
| 275 |
+
|
| 276 |
+
[*Note 3*:
|
| 277 |
+
|
| 278 |
+
The address of an array element or non-static data member is not an
|
| 279 |
+
acceptable *template-argument*.
|
| 280 |
+
|
| 281 |
+
[*Example 3*:
|
| 282 |
|
| 283 |
``` cpp
|
| 284 |
template<int* p> class X { };
|
| 285 |
|
| 286 |
int a[10];
|
| 287 |
struct S { int m; static int s; } s;
|
| 288 |
|
| 289 |
X<&a[2]> x3; // error: address of array element
|
| 290 |
X<&s.m> x4; // error: address of non-static member
|
| 291 |
+
X<&s.s> x5; // OK: address of static member
|
| 292 |
X<&S::s> x6; // OK: address of static member
|
| 293 |
```
|
| 294 |
|
| 295 |
+
— *end example*]
|
| 296 |
+
|
| 297 |
+
— *end note*]
|
| 298 |
+
|
| 299 |
+
[*Note 4*:
|
| 300 |
+
|
| 301 |
+
A temporary object is not an acceptable *template-argument* when the
|
| 302 |
+
corresponding *template-parameter* has reference type.
|
| 303 |
+
|
| 304 |
+
[*Example 4*:
|
| 305 |
|
| 306 |
``` cpp
|
| 307 |
+
template<const int& CRI> struct B { ... };
|
| 308 |
|
| 309 |
B<1> b2; // error: temporary would be required for template argument
|
| 310 |
|
| 311 |
int c = 1;
|
| 312 |
B<c> b1; // OK
|
| 313 |
```
|
| 314 |
|
| 315 |
+
— *end example*]
|
|
|
|
|
|
|
|
|
|
| 316 |
|
| 317 |
+
— *end note*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
|
| 319 |
### Template template arguments <a id="temp.arg.template">[[temp.arg.template]]</a>
|
| 320 |
|
| 321 |
A *template-argument* for a template *template-parameter* shall be the
|
| 322 |
name of a class template or an alias template, expressed as
|
|
|
|
| 329 |
Any partial specializations ([[temp.class.spec]]) associated with the
|
| 330 |
primary class template or primary variable template are considered when
|
| 331 |
a specialization based on the template *template-parameter* is
|
| 332 |
instantiated. If a specialization is not visible at the point of
|
| 333 |
instantiation, and it would have been selected had it been visible, the
|
| 334 |
+
program is ill-formed, no diagnostic required.
|
| 335 |
+
|
| 336 |
+
[*Example 1*:
|
| 337 |
|
| 338 |
``` cpp
|
| 339 |
template<class T> class A { // primary template
|
| 340 |
int x;
|
| 341 |
};
|
|
|
|
| 344 |
};
|
| 345 |
template<template<class U> class V> class C {
|
| 346 |
V<int> y;
|
| 347 |
V<int*> z;
|
| 348 |
};
|
| 349 |
+
C<A> c; // V<int> within C<A> uses the primary template, so c.y.x has type int
|
| 350 |
+
// V<int*> within C<A> uses the partial specialization, so c.z.x has type long
|
|
|
|
|
|
|
| 351 |
```
|
| 352 |
|
| 353 |
+
— *end example*]
|
| 354 |
+
|
| 355 |
+
A *template-argument* matches a template *template-parameter* `P` when
|
| 356 |
+
`P` is at least as specialized as the *template-argument* `A`. If `P`
|
| 357 |
+
contains a parameter pack, then `A` also matches `P` if each of `A`’s
|
| 358 |
+
template parameters matches the corresponding template parameter in the
|
| 359 |
+
*template-parameter-list* of `P`. Two template parameters match if they
|
| 360 |
+
are of the same kind (type, non-type, template), for non-type
|
| 361 |
+
*template-parameter*s, their types are equivalent ([[temp.over.link]]),
|
| 362 |
+
and for template *template-parameter*s, each of their corresponding
|
| 363 |
+
*template-parameter*s matches, recursively. When `P`’s
|
| 364 |
+
*template-parameter-list* contains a template parameter pack (
|
| 365 |
+
[[temp.variadic]]), the template parameter pack will match zero or more
|
| 366 |
+
template parameters or template parameter packs in the
|
| 367 |
+
*template-parameter-list* of `A` with the same type and form as the
|
| 368 |
+
template parameter pack in `P` (ignoring whether those template
|
| 369 |
+
parameters are template parameter packs).
|
| 370 |
+
|
| 371 |
+
[*Example 2*:
|
| 372 |
|
| 373 |
``` cpp
|
| 374 |
+
template<class T> class A { ... };
|
| 375 |
+
template<class T, class U = T> class B { ... };
|
| 376 |
+
template<class ... Types> class C { ... };
|
| 377 |
+
template<auto n> class D { ... };
|
| 378 |
+
template<template<class> class P> class X { ... };
|
| 379 |
+
template<template<class ...> class Q> class Y { ... };
|
| 380 |
+
template<template<int> class R> class Z { ... };
|
| 381 |
|
| 382 |
X<A> xa; // OK
|
| 383 |
+
X<B> xb; // OK
|
| 384 |
+
X<C> xc; // OK
|
|
|
|
| 385 |
Y<A> ya; // OK
|
| 386 |
Y<B> yb; // OK
|
| 387 |
Y<C> yc; // OK
|
| 388 |
+
Z<D> zd; // OK
|
| 389 |
```
|
| 390 |
|
| 391 |
+
— *end example*]
|
| 392 |
+
|
| 393 |
+
[*Example 3*:
|
| 394 |
+
|
| 395 |
``` cpp
|
| 396 |
template <class T> struct eval;
|
| 397 |
|
| 398 |
template <template <class, class...> class TT, class T1, class... Rest>
|
| 399 |
struct eval<TT<T1, Rest...>> { };
|
|
|
|
| 409 |
eval<C<17>> eC; // error: C does not match TT in partial specialization
|
| 410 |
eval<D<int, 17>> eD; // error: D does not match TT in partial specialization
|
| 411 |
eval<E<int, float>> eE; // error: E does not match TT in partial specialization
|
| 412 |
```
|
| 413 |
|
| 414 |
+
— *end example*]
|
| 415 |
+
|
| 416 |
+
A template *template-parameter* `P` is at least as specialized as a
|
| 417 |
+
template *template-argument* `A` if, given the following rewrite to two
|
| 418 |
+
function templates, the function template corresponding to `P` is at
|
| 419 |
+
least as specialized as the function template corresponding to `A`
|
| 420 |
+
according to the partial ordering rules for function templates (
|
| 421 |
+
[[temp.func.order]]). Given an invented class template `X` with the
|
| 422 |
+
template parameter list of `A` (including default arguments):
|
| 423 |
+
|
| 424 |
+
- Each of the two function templates has the same template parameters,
|
| 425 |
+
respectively, as `P` or `A`.
|
| 426 |
+
- Each function template has a single function parameter whose type is a
|
| 427 |
+
specialization of `X` with template arguments corresponding to the
|
| 428 |
+
template parameters from the respective function template where, for
|
| 429 |
+
each template parameter `PP` in the template parameter list of the
|
| 430 |
+
function template, a corresponding template argument `AA` is formed.
|
| 431 |
+
If `PP` declares a parameter pack, then `AA` is the pack expansion
|
| 432 |
+
`PP...` ([[temp.variadic]]); otherwise, `AA` is the *id-expression*
|
| 433 |
+
`PP`.
|
| 434 |
+
|
| 435 |
+
If the rewrite produces an invalid type, then `P` is not at least as
|
| 436 |
+
specialized as `A`.
|
| 437 |
+
|