tmp/tmp3kt43a3n/{from.md → to.md}
RENAMED
|
@@ -1,30 +1,38 @@
|
|
| 1 |
### Variadic templates <a id="temp.variadic">[[temp.variadic]]</a>
|
| 2 |
|
| 3 |
A *template parameter pack* is a template parameter that accepts zero or
|
| 4 |
more template arguments.
|
| 5 |
|
|
|
|
|
|
|
| 6 |
``` cpp
|
| 7 |
template<class ... Types> struct Tuple { };
|
| 8 |
|
| 9 |
Tuple<> t0; // Types contains no arguments
|
| 10 |
Tuple<int> t1; // Types contains one argument: int
|
| 11 |
Tuple<int, float> t2; // Types contains two arguments: int and float
|
| 12 |
Tuple<0> error; // error: 0 is not a type
|
| 13 |
```
|
| 14 |
|
|
|
|
|
|
|
| 15 |
A *function parameter pack* is a function parameter that accepts zero or
|
| 16 |
more function arguments.
|
| 17 |
|
|
|
|
|
|
|
| 18 |
``` cpp
|
| 19 |
template<class ... Types> void f(Types ... args);
|
| 20 |
|
| 21 |
f(); // OK: args contains no arguments
|
| 22 |
f(1); // OK: args contains one argument: int
|
| 23 |
f(2, 1.0); // OK: args contains two arguments: int and double
|
| 24 |
```
|
| 25 |
|
|
|
|
|
|
|
| 26 |
A *parameter pack* is either a template parameter pack or a function
|
| 27 |
parameter pack.
|
| 28 |
|
| 29 |
A *pack expansion* consists of a *pattern* and an ellipsis, the
|
| 30 |
instantiation of which produces zero or more instantiations of the
|
|
@@ -32,10 +40,12 @@ pattern in a list (described below). The form of the pattern depends on
|
|
| 32 |
the context in which the expansion occurs. Pack expansions can occur in
|
| 33 |
the following contexts:
|
| 34 |
|
| 35 |
- In a function parameter pack ([[dcl.fct]]); the pattern is the
|
| 36 |
*parameter-declaration* without the ellipsis.
|
|
|
|
|
|
|
| 37 |
- In a template parameter pack that is a pack expansion (
|
| 38 |
[[temp.param]]):
|
| 39 |
- if the template parameter pack is a *parameter-declaration*; the
|
| 40 |
pattern is the *parameter-declaration* without the ellipsis;
|
| 41 |
- if the template parameter pack is a *type-parameter* with a
|
|
@@ -48,43 +58,49 @@ the following contexts:
|
|
| 48 |
- In a *mem-initializer-list* ([[class.base.init]]) for a
|
| 49 |
*mem-initializer* whose *mem-initializer-id* denotes a base class; the
|
| 50 |
pattern is the *mem-initializer*.
|
| 51 |
- In a *template-argument-list* ([[temp.arg]]); the pattern is a
|
| 52 |
*template-argument*.
|
| 53 |
-
- In a *dynamic-exception-specification* ([[except.spec]]); the pattern
|
| 54 |
-
is a *type-id*.
|
| 55 |
- In an *attribute-list* ([[dcl.attr.grammar]]); the pattern is an
|
| 56 |
*attribute*.
|
| 57 |
- In an *alignment-specifier* ([[dcl.align]]); the pattern is the
|
| 58 |
*alignment-specifier* without the ellipsis.
|
| 59 |
- In a *capture-list* ([[expr.prim.lambda]]); the pattern is a
|
| 60 |
*capture*.
|
| 61 |
- In a `sizeof...` expression ([[expr.sizeof]]); the pattern is an
|
| 62 |
*identifier*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
For the purpose of determining whether a parameter pack satisfies a rule
|
| 65 |
regarding entities other than parameter packs, the parameter pack is
|
| 66 |
considered to be the entity that would result from an instantiation of
|
| 67 |
the pattern in which it appears.
|
| 68 |
|
| 69 |
-
``` cpp
|
| 70 |
-
template<class ... Types> void f(Types ... rest);
|
| 71 |
-
template<class ... Types> void g(Types ... rest) {
|
| 72 |
-
f(&rest ...); // ``&rest ...'' is a pack expansion; ``&rest'' is its pattern
|
| 73 |
-
}
|
| 74 |
-
```
|
| 75 |
-
|
| 76 |
A parameter pack whose name appears within the pattern of a pack
|
| 77 |
expansion is expanded by that pack expansion. An appearance of the name
|
| 78 |
of a parameter pack is only expanded by the innermost enclosing pack
|
| 79 |
expansion. The pattern of a pack expansion shall name one or more
|
| 80 |
parameter packs that are not expanded by a nested pack expansion; such
|
| 81 |
-
parameter packs are called *unexpanded
|
| 82 |
All of the parameter packs expanded by a pack expansion shall have the
|
| 83 |
same number of arguments specified. An appearance of a name of a
|
| 84 |
parameter pack that is not expanded is ill-formed.
|
| 85 |
|
|
|
|
|
|
|
| 86 |
``` cpp
|
| 87 |
template<typename...> struct Tuple {};
|
| 88 |
template<typename T1, typename T2> struct Pair {};
|
| 89 |
|
| 90 |
template<class ... Args1> struct zip {
|
|
@@ -101,38 +117,46 @@ typedef zip<short>::with<unsigned short, unsigned>::type T2;
|
|
| 101 |
template<class ... Args>
|
| 102 |
void g(Args ... args) { // OK: Args is expanded by the function parameter pack args
|
| 103 |
f(const_cast<const Args*>(&args)...); // OK: ``Args'' and ``args'' are expanded
|
| 104 |
f(5 ...); // error: pattern does not contain any parameter packs
|
| 105 |
f(args); // error: parameter pack ``args'' is not expanded
|
| 106 |
-
f(h(args ...) + args ...);
|
| 107 |
-
|
| 108 |
}
|
| 109 |
```
|
| 110 |
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
|
|
|
|
|
|
| 117 |
instantiation, is interpreted as follows:
|
| 118 |
|
| 119 |
- if the pack is a template parameter pack, the element is a template
|
| 120 |
parameter ([[temp.param]]) of the corresponding kind (type or
|
| 121 |
non-type) designating the type or value from the template argument;
|
| 122 |
otherwise,
|
| 123 |
- if the pack is a function parameter pack, the element is an
|
| 124 |
*id-expression* designating the function parameter that resulted from
|
| 125 |
the instantiation of the pattern where the pack is declared.
|
| 126 |
|
| 127 |
-
All of the Eᵢ become elements in the enclosing list.
|
| 128 |
-
|
| 129 |
-
*
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 134 |
|
| 135 |
``` cpp
|
| 136 |
template<class... T> struct X : T... { };
|
| 137 |
template<class... T> void f(T... values) {
|
| 138 |
X<T...> x(values...);
|
|
@@ -140,9 +164,55 @@ template<class... T> void f(T... values) {
|
|
| 140 |
|
| 141 |
template void f<>(); // OK: X<> has no base classes
|
| 142 |
// x is a variable of type X<> that is value-initialized
|
| 143 |
```
|
| 144 |
|
|
|
|
|
|
|
| 145 |
The instantiation of a `sizeof...` expression ([[expr.sizeof]])
|
| 146 |
produces an integral constant containing the number of elements in the
|
| 147 |
parameter pack it expands.
|
| 148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
### Variadic templates <a id="temp.variadic">[[temp.variadic]]</a>
|
| 2 |
|
| 3 |
A *template parameter pack* is a template parameter that accepts zero or
|
| 4 |
more template arguments.
|
| 5 |
|
| 6 |
+
[*Example 1*:
|
| 7 |
+
|
| 8 |
``` cpp
|
| 9 |
template<class ... Types> struct Tuple { };
|
| 10 |
|
| 11 |
Tuple<> t0; // Types contains no arguments
|
| 12 |
Tuple<int> t1; // Types contains one argument: int
|
| 13 |
Tuple<int, float> t2; // Types contains two arguments: int and float
|
| 14 |
Tuple<0> error; // error: 0 is not a type
|
| 15 |
```
|
| 16 |
|
| 17 |
+
— *end example*]
|
| 18 |
+
|
| 19 |
A *function parameter pack* is a function parameter that accepts zero or
|
| 20 |
more function arguments.
|
| 21 |
|
| 22 |
+
[*Example 2*:
|
| 23 |
+
|
| 24 |
``` cpp
|
| 25 |
template<class ... Types> void f(Types ... args);
|
| 26 |
|
| 27 |
f(); // OK: args contains no arguments
|
| 28 |
f(1); // OK: args contains one argument: int
|
| 29 |
f(2, 1.0); // OK: args contains two arguments: int and double
|
| 30 |
```
|
| 31 |
|
| 32 |
+
— *end example*]
|
| 33 |
+
|
| 34 |
A *parameter pack* is either a template parameter pack or a function
|
| 35 |
parameter pack.
|
| 36 |
|
| 37 |
A *pack expansion* consists of a *pattern* and an ellipsis, the
|
| 38 |
instantiation of which produces zero or more instantiations of the
|
|
|
|
| 40 |
the context in which the expansion occurs. Pack expansions can occur in
|
| 41 |
the following contexts:
|
| 42 |
|
| 43 |
- In a function parameter pack ([[dcl.fct]]); the pattern is the
|
| 44 |
*parameter-declaration* without the ellipsis.
|
| 45 |
+
- In a *using-declaration* ([[namespace.udecl]]); the pattern is a
|
| 46 |
+
*using-declarator*.
|
| 47 |
- In a template parameter pack that is a pack expansion (
|
| 48 |
[[temp.param]]):
|
| 49 |
- if the template parameter pack is a *parameter-declaration*; the
|
| 50 |
pattern is the *parameter-declaration* without the ellipsis;
|
| 51 |
- if the template parameter pack is a *type-parameter* with a
|
|
|
|
| 58 |
- In a *mem-initializer-list* ([[class.base.init]]) for a
|
| 59 |
*mem-initializer* whose *mem-initializer-id* denotes a base class; the
|
| 60 |
pattern is the *mem-initializer*.
|
| 61 |
- In a *template-argument-list* ([[temp.arg]]); the pattern is a
|
| 62 |
*template-argument*.
|
|
|
|
|
|
|
| 63 |
- In an *attribute-list* ([[dcl.attr.grammar]]); the pattern is an
|
| 64 |
*attribute*.
|
| 65 |
- In an *alignment-specifier* ([[dcl.align]]); the pattern is the
|
| 66 |
*alignment-specifier* without the ellipsis.
|
| 67 |
- In a *capture-list* ([[expr.prim.lambda]]); the pattern is a
|
| 68 |
*capture*.
|
| 69 |
- In a `sizeof...` expression ([[expr.sizeof]]); the pattern is an
|
| 70 |
*identifier*.
|
| 71 |
+
- In a *fold-expression* ([[expr.prim.fold]]); the pattern is the
|
| 72 |
+
*cast-expression* that contains an unexpanded parameter pack.
|
| 73 |
+
|
| 74 |
+
[*Example 3*:
|
| 75 |
+
|
| 76 |
+
``` cpp
|
| 77 |
+
template<class ... Types> void f(Types ... rest);
|
| 78 |
+
template<class ... Types> void g(Types ... rest) {
|
| 79 |
+
f(&rest ...); // ``&rest ...'' is a pack expansion; ``&rest'' is its pattern
|
| 80 |
+
}
|
| 81 |
+
```
|
| 82 |
+
|
| 83 |
+
— *end example*]
|
| 84 |
|
| 85 |
For the purpose of determining whether a parameter pack satisfies a rule
|
| 86 |
regarding entities other than parameter packs, the parameter pack is
|
| 87 |
considered to be the entity that would result from an instantiation of
|
| 88 |
the pattern in which it appears.
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
A parameter pack whose name appears within the pattern of a pack
|
| 91 |
expansion is expanded by that pack expansion. An appearance of the name
|
| 92 |
of a parameter pack is only expanded by the innermost enclosing pack
|
| 93 |
expansion. The pattern of a pack expansion shall name one or more
|
| 94 |
parameter packs that are not expanded by a nested pack expansion; such
|
| 95 |
+
parameter packs are called *unexpanded parameter packs* in the pattern.
|
| 96 |
All of the parameter packs expanded by a pack expansion shall have the
|
| 97 |
same number of arguments specified. An appearance of a name of a
|
| 98 |
parameter pack that is not expanded is ill-formed.
|
| 99 |
|
| 100 |
+
[*Example 4*:
|
| 101 |
+
|
| 102 |
``` cpp
|
| 103 |
template<typename...> struct Tuple {};
|
| 104 |
template<typename T1, typename T2> struct Pair {};
|
| 105 |
|
| 106 |
template<class ... Args1> struct zip {
|
|
|
|
| 117 |
template<class ... Args>
|
| 118 |
void g(Args ... args) { // OK: Args is expanded by the function parameter pack args
|
| 119 |
f(const_cast<const Args*>(&args)...); // OK: ``Args'' and ``args'' are expanded
|
| 120 |
f(5 ...); // error: pattern does not contain any parameter packs
|
| 121 |
f(args); // error: parameter pack ``args'' is not expanded
|
| 122 |
+
f(h(args ...) + args ...); // OK: first ``args'' expanded within h,
|
| 123 |
+
// second ``args'' expanded within f
|
| 124 |
}
|
| 125 |
```
|
| 126 |
|
| 127 |
+
— *end example*]
|
| 128 |
+
|
| 129 |
+
The instantiation of a pack expansion that is neither a `sizeof...`
|
| 130 |
+
expression nor a *fold-expression* produces a list
|
| 131 |
+
$\mathtt{E}_1, \mathtt{E}_2, \dotsc, \mathtt{E}_N$, where N is the
|
| 132 |
+
number of elements in the pack expansion parameters. Each Eᵢ is
|
| 133 |
+
generated by instantiating the pattern and replacing each pack expansion
|
| 134 |
+
parameter with its ith element. Such an element, in the context of the
|
| 135 |
instantiation, is interpreted as follows:
|
| 136 |
|
| 137 |
- if the pack is a template parameter pack, the element is a template
|
| 138 |
parameter ([[temp.param]]) of the corresponding kind (type or
|
| 139 |
non-type) designating the type or value from the template argument;
|
| 140 |
otherwise,
|
| 141 |
- if the pack is a function parameter pack, the element is an
|
| 142 |
*id-expression* designating the function parameter that resulted from
|
| 143 |
the instantiation of the pattern where the pack is declared.
|
| 144 |
|
| 145 |
+
All of the Eᵢ become elements in the enclosing list.
|
| 146 |
+
|
| 147 |
+
[*Note 1*: The variety of list varies with the context:
|
| 148 |
+
*expression-list*, *base-specifier-list*, *template-argument-list*,
|
| 149 |
+
etc. — *end note*]
|
| 150 |
+
|
| 151 |
+
When N is zero, the instantiation of the expansion produces an empty
|
| 152 |
+
list. Such an instantiation does not alter the syntactic interpretation
|
| 153 |
+
of the enclosing construct, even in cases where omitting the list
|
| 154 |
+
entirely would otherwise be ill-formed or would result in an ambiguity
|
| 155 |
+
in the grammar.
|
| 156 |
+
|
| 157 |
+
[*Example 5*:
|
| 158 |
|
| 159 |
``` cpp
|
| 160 |
template<class... T> struct X : T... { };
|
| 161 |
template<class... T> void f(T... values) {
|
| 162 |
X<T...> x(values...);
|
|
|
|
| 164 |
|
| 165 |
template void f<>(); // OK: X<> has no base classes
|
| 166 |
// x is a variable of type X<> that is value-initialized
|
| 167 |
```
|
| 168 |
|
| 169 |
+
— *end example*]
|
| 170 |
+
|
| 171 |
The instantiation of a `sizeof...` expression ([[expr.sizeof]])
|
| 172 |
produces an integral constant containing the number of elements in the
|
| 173 |
parameter pack it expands.
|
| 174 |
|
| 175 |
+
The instantiation of a *fold-expression* produces:
|
| 176 |
+
|
| 177 |
+
- `((`E₁ *op* E₂`)` *op* ⋯`)` *op* $\mathtt{E}_N$ for a unary left fold,
|
| 178 |
+
- E₁ *op* `(`⋯ *op* `(`$\mathtt{E}_{N-1}$ *op* $\mathtt{E}_N$`))` for a
|
| 179 |
+
unary right fold,
|
| 180 |
+
- `(((`E *op* E₁`)` *op* E₂`)` *op* ⋯`)` *op* $\mathtt{E}_N$ for a
|
| 181 |
+
binary left fold, and
|
| 182 |
+
- E₁ *op* `(`⋯ *op* `(`$\mathtt{E}_{N-1}$ *op* `(`$\mathtt{E}_{N}$ *op*
|
| 183 |
+
E`)))` for a binary right fold.
|
| 184 |
+
|
| 185 |
+
In each case, *op* is the *fold-operator*, N is the number of elements
|
| 186 |
+
in the pack expansion parameters, and each Eᵢ is generated by
|
| 187 |
+
instantiating the pattern and replacing each pack expansion parameter
|
| 188 |
+
with its ith element. For a binary fold-expression, E is generated by
|
| 189 |
+
instantiating the *cast-expression* that did not contain an unexpanded
|
| 190 |
+
parameter pack.
|
| 191 |
+
|
| 192 |
+
[*Example 6*:
|
| 193 |
+
|
| 194 |
+
``` cpp
|
| 195 |
+
template<typename ...Args>
|
| 196 |
+
bool all(Args ...args) { return (... && args); }
|
| 197 |
+
|
| 198 |
+
bool b = all(true, true, true, false);
|
| 199 |
+
```
|
| 200 |
+
|
| 201 |
+
Within the instantiation of `all`, the returned expression expands to
|
| 202 |
+
`((true && true) && true) && false`, which evaluates to `false`.
|
| 203 |
+
|
| 204 |
+
— *end example*]
|
| 205 |
+
|
| 206 |
+
If N is zero for a unary fold-expression, the value of the expression is
|
| 207 |
+
shown in Table [[tab:fold.empty]]; if the operator is not listed in
|
| 208 |
+
Table [[tab:fold.empty]], the instantiation is ill-formed.
|
| 209 |
+
|
| 210 |
+
**Table: Value of folding empty sequences** <a id="tab:fold.empty">[tab:fold.empty]</a>
|
| 211 |
+
|
| 212 |
+
| Operator | Value when parameter pack is empty |
|
| 213 |
+
| -------- | ---------------------------------- |
|
| 214 |
+
| `&&` | `true` |
|
| 215 |
+
| `||` | `false` |
|
| 216 |
+
| `,` | `void()` |
|
| 217 |
+
|
| 218 |
+
|