- tmp/tmpd0bs846x/{from.md → to.md} +117 -61
tmp/tmpd0bs846x/{from.md → to.md}
RENAMED
|
@@ -8,50 +8,37 @@ template-parameter:
|
|
| 8 |
parameter-declaration
|
| 9 |
```
|
| 10 |
|
| 11 |
``` bnf
|
| 12 |
type-parameter:
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
'
|
| 16 |
-
'
|
| 17 |
-
'template <' template-parameter-list '> class' '...'ₒₚₜ identifierₒₚₜ
|
| 18 |
-
'template <' template-parameter-list '> class' identifierₒₚₜ '=' id-expression
|
| 19 |
```
|
| 20 |
|
| 21 |
-
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
There is no semantic difference between `class` and `typename` in a
|
| 25 |
-
*
|
| 26 |
template type parameter. `typename` followed by a *qualified-id* denotes
|
| 27 |
-
the type in a non-type [^1] *parameter-declaration*. A
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
parameter may be a class template. For example,
|
| 31 |
|
| 32 |
-
|
| 33 |
-
template<class T> class myarray { /* ... */ };
|
| 34 |
-
|
| 35 |
-
template<class K, class V, template<class T> class C = myarray>
|
| 36 |
-
class Map {
|
| 37 |
-
C<K> key;
|
| 38 |
-
C<V> value;
|
| 39 |
-
};
|
| 40 |
-
```
|
| 41 |
-
|
| 42 |
-
A *type-parameter* whose identifier does not follow an ellipsis defines
|
| 43 |
-
its *identifier* to be a *typedef-name* (if declared with `class` or
|
| 44 |
-
`typename`) or *template-name* (if declared with `template`) in the
|
| 45 |
-
scope of the template declaration. Because of the name lookup rules, a
|
| 46 |
-
*template-parameter* that could be interpreted as either a non-type
|
| 47 |
-
*template-parameter* or a *type-parameter* (because its *identifier* is
|
| 48 |
-
the name of an already existing class) is taken as a *type-parameter*.
|
| 49 |
-
For example,
|
| 50 |
|
| 51 |
``` cpp
|
| 52 |
-
class T {
|
| 53 |
int i;
|
| 54 |
|
| 55 |
template<class T, T i> void f(T t) {
|
| 56 |
T t1 = i; // template-parameters T and i
|
| 57 |
::T t2 = ::i; // global namespace members T and i
|
|
@@ -59,30 +46,63 @@ template<class T, T i> void f(T t) {
|
|
| 59 |
```
|
| 60 |
|
| 61 |
Here, the template `f` has a *type-parameter* called `T`, rather than an
|
| 62 |
unnamed non-type *template-parameter* of class `T`.
|
| 63 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
A non-type *template-parameter* shall have one of the following
|
| 65 |
-
(optionally
|
| 66 |
|
| 67 |
- integral or enumeration type,
|
| 68 |
- pointer to object or pointer to function,
|
| 69 |
- lvalue reference to object or lvalue reference to function,
|
| 70 |
- pointer to member,
|
| 71 |
-
- `std::nullptr_t`
|
|
|
|
| 72 |
|
| 73 |
-
Other types are disallowed either explicitly below or
|
| 74 |
-
rules governing the form of *template-argument*s (
|
| 75 |
-
|
| 76 |
-
|
|
|
|
|
|
|
| 77 |
|
| 78 |
A non-type non-reference *template-parameter* is a prvalue. It shall not
|
| 79 |
be assigned to or in any other way have its value changed. A non-type
|
| 80 |
non-reference *template-parameter* cannot have its address taken. When a
|
| 81 |
non-type non-reference *template-parameter* is used as an initializer
|
| 82 |
for a reference, a temporary is always used.
|
| 83 |
|
|
|
|
|
|
|
| 84 |
``` cpp
|
| 85 |
template<const X& x, int i> void f() {
|
| 86 |
i++; // error: change of template-parameter value
|
| 87 |
|
| 88 |
&x; // OK
|
|
@@ -91,34 +111,43 @@ template<const X& x, int i> void f() {
|
|
| 91 |
int& ri = i; // error: non-const reference bound to temporary
|
| 92 |
const int& cri = i; // OK: const reference bound to temporary
|
| 93 |
}
|
| 94 |
```
|
| 95 |
|
| 96 |
-
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
``` cpp
|
| 100 |
template<double d> class X; // error
|
| 101 |
template<double* pd> class Y; // OK
|
| 102 |
template<double& rd> class Z; // OK
|
| 103 |
```
|
| 104 |
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
| 108 |
|
| 109 |
``` cpp
|
| 110 |
-
template<int* a> struct R {
|
| 111 |
-
template<int b[5]> struct S {
|
| 112 |
int p;
|
| 113 |
R<&p> w; // OK
|
| 114 |
S<&p> x; // OK due to parameter adjustment
|
| 115 |
int v[5];
|
| 116 |
R<v> y; // OK due to implicit argument conversion
|
| 117 |
S<v> z; // OK due to both adjustment and conversion
|
| 118 |
```
|
| 119 |
|
|
|
|
|
|
|
| 120 |
A *default template-argument* is a *template-argument* ([[temp.arg]])
|
| 121 |
specified after `=` in a *template-parameter*. A default
|
| 122 |
*template-argument* may be specified for any kind of
|
| 123 |
*template-parameter* (type, non-type, template) that is not a template
|
| 124 |
parameter pack ([[temp.variadic]]). A default *template-argument* may
|
|
@@ -129,16 +158,17 @@ member’s class. A default *template-argument* shall not be specified in
|
|
| 129 |
a friend class template declaration. If a friend function template
|
| 130 |
declaration specifies a default *template-argument*, that declaration
|
| 131 |
shall be a definition and shall be the only declaration of the function
|
| 132 |
template in the translation unit.
|
| 133 |
|
| 134 |
-
The set of default *template-argument*s available for use
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
scope in the same way default function arguments are (
|
| 138 |
[[dcl.fct.default]]).
|
| 139 |
|
|
|
|
|
|
|
| 140 |
``` cpp
|
| 141 |
template<class T1, class T2 = int> class A;
|
| 142 |
template<class T1 = int, class T2> class A;
|
| 143 |
```
|
| 144 |
|
|
@@ -146,53 +176,73 @@ is equivalent to
|
|
| 146 |
|
| 147 |
``` cpp
|
| 148 |
template<class T1 = int, class T2 = int> class A;
|
| 149 |
```
|
| 150 |
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
parameter
|
| 159 |
-
template
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
``` cpp
|
| 162 |
template<class T1 = int, class T2> class B; // error
|
| 163 |
|
| 164 |
// U can be neither deduced from the parameter-type-list nor specified
|
| 165 |
template<class... T, class... U> void f() { } // error
|
| 166 |
template<class... T, class U> void g() { } // error
|
| 167 |
```
|
| 168 |
|
|
|
|
|
|
|
| 169 |
A *template-parameter* shall not be given default arguments by two
|
| 170 |
different declarations in the same scope.
|
| 171 |
|
|
|
|
|
|
|
| 172 |
``` cpp
|
| 173 |
template<class T = int> class X;
|
| 174 |
-
template<class T = int> class X {
|
| 175 |
```
|
| 176 |
|
|
|
|
|
|
|
| 177 |
When parsing a default *template-argument* for a non-type
|
| 178 |
*template-parameter*, the first non-nested `>` is taken as the end of
|
| 179 |
the *template-parameter-list* rather than a greater-than operator.
|
| 180 |
|
|
|
|
|
|
|
| 181 |
``` cpp
|
| 182 |
template<int i = 3 > 4 > // syntax error
|
| 183 |
-
class X {
|
| 184 |
|
| 185 |
template<int i = (3 > 4) > // OK
|
| 186 |
-
class Y {
|
| 187 |
```
|
| 188 |
|
|
|
|
|
|
|
| 189 |
A *template-parameter* of a template *template-parameter* is permitted
|
| 190 |
to have a default *template-argument*. When such default arguments are
|
| 191 |
specified, they apply to the template *template-parameter* in the scope
|
| 192 |
of the template *template-parameter*.
|
| 193 |
|
|
|
|
|
|
|
| 194 |
``` cpp
|
| 195 |
template <class T = float> struct B {};
|
| 196 |
template <template <class TT = float> class T> struct A {
|
| 197 |
inline void f();
|
| 198 |
inline void g();
|
|
@@ -203,10 +253,12 @@ template <template <class TT> class T> void A<T>::f() {
|
|
| 203 |
template <template <class TT = char> class T> void A<T>::g() {
|
| 204 |
T<> t; // OK - T<char>
|
| 205 |
}
|
| 206 |
```
|
| 207 |
|
|
|
|
|
|
|
| 208 |
If a *template-parameter* is a *type-parameter* with an ellipsis prior
|
| 209 |
to its optional *identifier* or is a *parameter-declaration* that
|
| 210 |
declares a parameter pack ([[dcl.fct]]), then the *template-parameter*
|
| 211 |
is a template parameter pack ([[temp.variadic]]). A template parameter
|
| 212 |
pack that is a *parameter-declaration* whose type contains one or more
|
|
@@ -215,10 +267,12 @@ parameter pack that is a *type-parameter* with a
|
|
| 215 |
*template-parameter-list* containing one or more unexpanded parameter
|
| 216 |
packs is a pack expansion. A template parameter pack that is a pack
|
| 217 |
expansion shall not expand a parameter pack declared in the same
|
| 218 |
*template-parameter-list*.
|
| 219 |
|
|
|
|
|
|
|
| 220 |
``` cpp
|
| 221 |
template <class... Types> class Tuple; // Types is a template type parameter pack
|
| 222 |
// but not a pack expansion
|
| 223 |
template <class T, int... Dims> struct multi_array; // Dims is a non-type template parameter pack
|
| 224 |
// but not a pack expansion
|
|
@@ -228,5 +282,7 @@ template<class... T> struct value_holder {
|
|
| 228 |
};
|
| 229 |
template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
|
| 230 |
// pack T within the same template parameter list
|
| 231 |
```
|
| 232 |
|
|
|
|
|
|
|
|
|
| 8 |
parameter-declaration
|
| 9 |
```
|
| 10 |
|
| 11 |
``` bnf
|
| 12 |
type-parameter:
|
| 13 |
+
type-parameter-key '...'ₒₚₜ identifierₒₚₜ
|
| 14 |
+
type-parameter-key identifierₒₚₜ '=' type-id
|
| 15 |
+
'template <' template-parameter-list '>' type-parameter-key '...'ₒₚₜ identifierₒₚₜ
|
| 16 |
+
'template <' template-parameter-list '>' type-parameter-key identifierₒₚₜ '=' id-expression
|
|
|
|
|
|
|
| 17 |
```
|
| 18 |
|
| 19 |
+
``` bnf
|
| 20 |
+
type-parameter-key:
|
| 21 |
+
'class'
|
| 22 |
+
'typename'
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
[*Note 1*: The `>` token following the *template-parameter-list* of a
|
| 26 |
+
*type-parameter* may be the product of replacing a `>{>}` token by two
|
| 27 |
+
consecutive `>` tokens ([[temp.names]]). — *end note*]
|
| 28 |
|
| 29 |
There is no semantic difference between `class` and `typename` in a
|
| 30 |
+
*type-parameter-key*. `typename` followed by an *unqualified-id* names a
|
| 31 |
template type parameter. `typename` followed by a *qualified-id* denotes
|
| 32 |
+
the type in a non-type [^1] *parameter-declaration*. A
|
| 33 |
+
*template-parameter* of the form `class` *identifier* is a
|
| 34 |
+
*type-parameter*.
|
|
|
|
| 35 |
|
| 36 |
+
[*Example 1*:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
``` cpp
|
| 39 |
+
class T { ... };
|
| 40 |
int i;
|
| 41 |
|
| 42 |
template<class T, T i> void f(T t) {
|
| 43 |
T t1 = i; // template-parameters T and i
|
| 44 |
::T t2 = ::i; // global namespace members T and i
|
|
|
|
| 46 |
```
|
| 47 |
|
| 48 |
Here, the template `f` has a *type-parameter* called `T`, rather than an
|
| 49 |
unnamed non-type *template-parameter* of class `T`.
|
| 50 |
|
| 51 |
+
— *end example*]
|
| 52 |
+
|
| 53 |
+
A storage class shall not be specified in a *template-parameter*
|
| 54 |
+
declaration. Types shall not be defined in a *template-parameter*
|
| 55 |
+
declaration.
|
| 56 |
+
|
| 57 |
+
A *type-parameter* whose identifier does not follow an ellipsis defines
|
| 58 |
+
its *identifier* to be a *typedef-name* (if declared without `template`)
|
| 59 |
+
or *template-name* (if declared with `template`) in the scope of the
|
| 60 |
+
template declaration.
|
| 61 |
+
|
| 62 |
+
[*Note 2*:
|
| 63 |
+
|
| 64 |
+
A template argument may be a class template or alias template. For
|
| 65 |
+
example,
|
| 66 |
+
|
| 67 |
+
``` cpp
|
| 68 |
+
template<class T> class myarray { ... };
|
| 69 |
+
|
| 70 |
+
template<class K, class V, template<class T> class C = myarray>
|
| 71 |
+
class Map {
|
| 72 |
+
C<K> key;
|
| 73 |
+
C<V> value;
|
| 74 |
+
};
|
| 75 |
+
```
|
| 76 |
+
|
| 77 |
+
— *end note*]
|
| 78 |
+
|
| 79 |
A non-type *template-parameter* shall have one of the following
|
| 80 |
+
(optionally cv-qualified) types:
|
| 81 |
|
| 82 |
- integral or enumeration type,
|
| 83 |
- pointer to object or pointer to function,
|
| 84 |
- lvalue reference to object or lvalue reference to function,
|
| 85 |
- pointer to member,
|
| 86 |
+
- `std::nullptr_t`, or
|
| 87 |
+
- a type that contains a placeholder type ([[dcl.spec.auto]]).
|
| 88 |
|
| 89 |
+
[*Note 3*: Other types are disallowed either explicitly below or
|
| 90 |
+
implicitly by the rules governing the form of *template-argument*s (
|
| 91 |
+
[[temp.arg]]). — *end note*]
|
| 92 |
+
|
| 93 |
+
The top-level *cv-qualifier*s on the *template-parameter* are ignored
|
| 94 |
+
when determining its type.
|
| 95 |
|
| 96 |
A non-type non-reference *template-parameter* is a prvalue. It shall not
|
| 97 |
be assigned to or in any other way have its value changed. A non-type
|
| 98 |
non-reference *template-parameter* cannot have its address taken. When a
|
| 99 |
non-type non-reference *template-parameter* is used as an initializer
|
| 100 |
for a reference, a temporary is always used.
|
| 101 |
|
| 102 |
+
[*Example 2*:
|
| 103 |
+
|
| 104 |
``` cpp
|
| 105 |
template<const X& x, int i> void f() {
|
| 106 |
i++; // error: change of template-parameter value
|
| 107 |
|
| 108 |
&x; // OK
|
|
|
|
| 111 |
int& ri = i; // error: non-const reference bound to temporary
|
| 112 |
const int& cri = i; // OK: const reference bound to temporary
|
| 113 |
}
|
| 114 |
```
|
| 115 |
|
| 116 |
+
— *end example*]
|
| 117 |
+
|
| 118 |
+
A non-type *template-parameter* shall not be declared to have
|
| 119 |
+
floating-point, class, or void type.
|
| 120 |
+
|
| 121 |
+
[*Example 3*:
|
| 122 |
|
| 123 |
``` cpp
|
| 124 |
template<double d> class X; // error
|
| 125 |
template<double* pd> class Y; // OK
|
| 126 |
template<double& rd> class Z; // OK
|
| 127 |
```
|
| 128 |
|
| 129 |
+
— *end example*]
|
| 130 |
+
|
| 131 |
+
A non-type *template-parameter* of type “array of `T`” or of function
|
| 132 |
+
type `T` is adjusted to be of type “pointer to `T`”.
|
| 133 |
+
|
| 134 |
+
[*Example 4*:
|
| 135 |
|
| 136 |
``` cpp
|
| 137 |
+
template<int* a> struct R { ... };
|
| 138 |
+
template<int b[5]> struct S { ... };
|
| 139 |
int p;
|
| 140 |
R<&p> w; // OK
|
| 141 |
S<&p> x; // OK due to parameter adjustment
|
| 142 |
int v[5];
|
| 143 |
R<v> y; // OK due to implicit argument conversion
|
| 144 |
S<v> z; // OK due to both adjustment and conversion
|
| 145 |
```
|
| 146 |
|
| 147 |
+
— *end example*]
|
| 148 |
+
|
| 149 |
A *default template-argument* is a *template-argument* ([[temp.arg]])
|
| 150 |
specified after `=` in a *template-parameter*. A default
|
| 151 |
*template-argument* may be specified for any kind of
|
| 152 |
*template-parameter* (type, non-type, template) that is not a template
|
| 153 |
parameter pack ([[temp.variadic]]). A default *template-argument* may
|
|
|
|
| 158 |
a friend class template declaration. If a friend function template
|
| 159 |
declaration specifies a default *template-argument*, that declaration
|
| 160 |
shall be a definition and shall be the only declaration of the function
|
| 161 |
template in the translation unit.
|
| 162 |
|
| 163 |
+
The set of default *template-argument*s available for use is obtained by
|
| 164 |
+
merging the default arguments from all prior declarations of the
|
| 165 |
+
template in the same way default function arguments are (
|
|
|
|
| 166 |
[[dcl.fct.default]]).
|
| 167 |
|
| 168 |
+
[*Example 5*:
|
| 169 |
+
|
| 170 |
``` cpp
|
| 171 |
template<class T1, class T2 = int> class A;
|
| 172 |
template<class T1 = int, class T2> class A;
|
| 173 |
```
|
| 174 |
|
|
|
|
| 176 |
|
| 177 |
``` cpp
|
| 178 |
template<class T1 = int, class T2 = int> class A;
|
| 179 |
```
|
| 180 |
|
| 181 |
+
— *end example*]
|
| 182 |
+
|
| 183 |
+
If a *template-parameter* of a class template, variable template, or
|
| 184 |
+
alias template has a default *template-argument*, each subsequent
|
| 185 |
+
*template-parameter* shall either have a default *template-argument*
|
| 186 |
+
supplied or be a template parameter pack. If a *template-parameter* of a
|
| 187 |
+
primary class template, primary variable template, or alias template is
|
| 188 |
+
a template parameter pack, it shall be the last *template-parameter*. A
|
| 189 |
+
template parameter pack of a function template shall not be followed by
|
| 190 |
+
another template parameter unless that template parameter can be deduced
|
| 191 |
+
from the parameter-type-list ([[dcl.fct]]) of the function template or
|
| 192 |
+
has a default argument ([[temp.deduct]]). A template parameter of a
|
| 193 |
+
deduction guide template ([[temp.deduct.guide]]) that does not have a
|
| 194 |
+
default argument shall be deducible from the parameter-type-list of the
|
| 195 |
+
deduction guide template.
|
| 196 |
+
|
| 197 |
+
[*Example 6*:
|
| 198 |
|
| 199 |
``` cpp
|
| 200 |
template<class T1 = int, class T2> class B; // error
|
| 201 |
|
| 202 |
// U can be neither deduced from the parameter-type-list nor specified
|
| 203 |
template<class... T, class... U> void f() { } // error
|
| 204 |
template<class... T, class U> void g() { } // error
|
| 205 |
```
|
| 206 |
|
| 207 |
+
— *end example*]
|
| 208 |
+
|
| 209 |
A *template-parameter* shall not be given default arguments by two
|
| 210 |
different declarations in the same scope.
|
| 211 |
|
| 212 |
+
[*Example 7*:
|
| 213 |
+
|
| 214 |
``` cpp
|
| 215 |
template<class T = int> class X;
|
| 216 |
+
template<class T = int> class X { ... }; // error
|
| 217 |
```
|
| 218 |
|
| 219 |
+
— *end example*]
|
| 220 |
+
|
| 221 |
When parsing a default *template-argument* for a non-type
|
| 222 |
*template-parameter*, the first non-nested `>` is taken as the end of
|
| 223 |
the *template-parameter-list* rather than a greater-than operator.
|
| 224 |
|
| 225 |
+
[*Example 8*:
|
| 226 |
+
|
| 227 |
``` cpp
|
| 228 |
template<int i = 3 > 4 > // syntax error
|
| 229 |
+
class X { ... };
|
| 230 |
|
| 231 |
template<int i = (3 > 4) > // OK
|
| 232 |
+
class Y { ... };
|
| 233 |
```
|
| 234 |
|
| 235 |
+
— *end example*]
|
| 236 |
+
|
| 237 |
A *template-parameter* of a template *template-parameter* is permitted
|
| 238 |
to have a default *template-argument*. When such default arguments are
|
| 239 |
specified, they apply to the template *template-parameter* in the scope
|
| 240 |
of the template *template-parameter*.
|
| 241 |
|
| 242 |
+
[*Example 9*:
|
| 243 |
+
|
| 244 |
``` cpp
|
| 245 |
template <class T = float> struct B {};
|
| 246 |
template <template <class TT = float> class T> struct A {
|
| 247 |
inline void f();
|
| 248 |
inline void g();
|
|
|
|
| 253 |
template <template <class TT = char> class T> void A<T>::g() {
|
| 254 |
T<> t; // OK - T<char>
|
| 255 |
}
|
| 256 |
```
|
| 257 |
|
| 258 |
+
— *end example*]
|
| 259 |
+
|
| 260 |
If a *template-parameter* is a *type-parameter* with an ellipsis prior
|
| 261 |
to its optional *identifier* or is a *parameter-declaration* that
|
| 262 |
declares a parameter pack ([[dcl.fct]]), then the *template-parameter*
|
| 263 |
is a template parameter pack ([[temp.variadic]]). A template parameter
|
| 264 |
pack that is a *parameter-declaration* whose type contains one or more
|
|
|
|
| 267 |
*template-parameter-list* containing one or more unexpanded parameter
|
| 268 |
packs is a pack expansion. A template parameter pack that is a pack
|
| 269 |
expansion shall not expand a parameter pack declared in the same
|
| 270 |
*template-parameter-list*.
|
| 271 |
|
| 272 |
+
[*Example 10*:
|
| 273 |
+
|
| 274 |
``` cpp
|
| 275 |
template <class... Types> class Tuple; // Types is a template type parameter pack
|
| 276 |
// but not a pack expansion
|
| 277 |
template <class T, int... Dims> struct multi_array; // Dims is a non-type template parameter pack
|
| 278 |
// but not a pack expansion
|
|
|
|
| 282 |
};
|
| 283 |
template<class... T, T... Values> struct static_array;// error: Values expands template type parameter
|
| 284 |
// pack T within the same template parameter list
|
| 285 |
```
|
| 286 |
|
| 287 |
+
— *end example*]
|
| 288 |
+
|