tmp/tmpf8r_bips/{from.md → to.md}
RENAMED
|
@@ -127,94 +127,72 @@ template<class ... Args1> struct zip {
|
|
| 127 |
typedef Tuple<Pair<Args1, Args2> ... > type;
|
| 128 |
};
|
| 129 |
};
|
| 130 |
|
| 131 |
typedef zip<short, int>::with<unsigned short, unsigned>::type T1;
|
| 132 |
-
// T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>
|
| 133 |
typedef zip<short>::with<unsigned short, unsigned>::type T2;
|
| 134 |
// error: different number of arguments specified for Args1 and Args2
|
| 135 |
|
| 136 |
template<class ... Args>
|
| 137 |
-
void g(Args ... args) { // OK
|
| 138 |
-
f(const_cast<const Args*>(&args)...); // OK
|
| 139 |
f(5 ...); // error: pattern does not contain any packs
|
| 140 |
f(args); // error: pack ``args'' is not expanded
|
| 141 |
-
f(h(args ...) + args ...); // OK
|
| 142 |
// second ``args'' expanded within f
|
| 143 |
}
|
| 144 |
```
|
| 145 |
|
| 146 |
— *end example*]
|
| 147 |
|
| 148 |
-
The instantiation of a pack expansion
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
follows:
|
| 155 |
|
| 156 |
-
- if the pack is a template parameter pack, the element is
|
| 157 |
-
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
| 159 |
- if the pack is a function parameter pack, the element is an
|
| 160 |
*id-expression* designating the iᵗʰ function parameter that resulted
|
| 161 |
from instantiation of the function parameter pack declaration;
|
| 162 |
otherwise
|
| 163 |
- if the pack is an *init-capture* pack, the element is an
|
| 164 |
*id-expression* designating the variable introduced by the iᵗʰ
|
| 165 |
*init-capture* that resulted from instantiation of the *init-capture*
|
| 166 |
-
pack.
|
| 167 |
|
| 168 |
-
|
| 169 |
-
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
etc. — *end note*]
|
| 173 |
-
|
| 174 |
-
When N is zero, the instantiation of the expansion produces an empty
|
| 175 |
-
list. Such an instantiation does not alter the syntactic interpretation
|
| 176 |
-
of the enclosing construct, even in cases where omitting the list
|
| 177 |
-
entirely would otherwise be ill-formed or would result in an ambiguity
|
| 178 |
-
in the grammar.
|
| 179 |
-
|
| 180 |
-
[*Example 6*:
|
| 181 |
-
|
| 182 |
-
``` cpp
|
| 183 |
-
template<class... T> struct X : T... { };
|
| 184 |
-
template<class... T> void f(T... values) {
|
| 185 |
-
X<T...> x(values...);
|
| 186 |
-
}
|
| 187 |
-
|
| 188 |
-
template void f<>(); // OK: X<> has no base classes
|
| 189 |
-
// x is a variable of type X<> that is value-initialized
|
| 190 |
-
```
|
| 191 |
-
|
| 192 |
-
— *end example*]
|
| 193 |
|
| 194 |
The instantiation of a `sizeof...` expression [[expr.sizeof]] produces
|
| 195 |
-
an integral constant
|
| 196 |
-
expands.
|
| 197 |
|
| 198 |
-
The instantiation of a *fold-expression* produces:
|
| 199 |
|
| 200 |
-
- `((`E₁ *op* E₂`)` *op* ⋯`)` *op* $\mathtt{E}_N$ for a unary
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
|
|
|
| 207 |
|
| 208 |
-
In each case, *op* is the *fold-operator*
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
with its iᵗʰ element. For a binary fold-expression, E is generated by
|
| 212 |
-
instantiating the *cast-expression* that did not contain an unexpanded
|
| 213 |
-
pack.
|
| 214 |
|
| 215 |
-
[*Example
|
| 216 |
|
| 217 |
``` cpp
|
| 218 |
template<typename ...Args>
|
| 219 |
bool all(Args ...args) { return (... && args); }
|
| 220 |
|
|
@@ -224,12 +202,12 @@ bool b = all(true, true, true, false);
|
|
| 224 |
Within the instantiation of `all`, the returned expression expands to
|
| 225 |
`((true && true) && true) && false`, which evaluates to `false`.
|
| 226 |
|
| 227 |
— *end example*]
|
| 228 |
|
| 229 |
-
If N is zero for a unary fold
|
| 230 |
-
|
| 231 |
[[temp.fold.empty]], the instantiation is ill-formed.
|
| 232 |
|
| 233 |
**Table: Value of folding empty sequences** <a id="temp.fold.empty">[temp.fold.empty]</a>
|
| 234 |
|
| 235 |
| Operator | Value when pack is empty |
|
|
@@ -237,5 +215,29 @@ shown in [[temp.fold.empty]]; if the operator is not listed in
|
|
| 237 |
| `&&` | `true` |
|
| 238 |
| `||` | `false` |
|
| 239 |
| `,` | `void()` |
|
| 240 |
|
| 241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
typedef Tuple<Pair<Args1, Args2> ... > type;
|
| 128 |
};
|
| 129 |
};
|
| 130 |
|
| 131 |
typedef zip<short, int>::with<unsigned short, unsigned>::type T1;
|
| 132 |
+
// T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>>
|
| 133 |
typedef zip<short>::with<unsigned short, unsigned>::type T2;
|
| 134 |
// error: different number of arguments specified for Args1 and Args2
|
| 135 |
|
| 136 |
template<class ... Args>
|
| 137 |
+
void g(Args ... args) { // OK, Args is expanded by the function parameter pack args
|
| 138 |
+
f(const_cast<const Args*>(&args)...); // OK, ``Args'' and ``args'' are expanded
|
| 139 |
f(5 ...); // error: pattern does not contain any packs
|
| 140 |
f(args); // error: pack ``args'' is not expanded
|
| 141 |
+
f(h(args ...) + args ...); // OK, first ``args'' expanded within h,
|
| 142 |
// second ``args'' expanded within f
|
| 143 |
}
|
| 144 |
```
|
| 145 |
|
| 146 |
— *end example*]
|
| 147 |
|
| 148 |
+
The instantiation of a pack expansion considers items
|
| 149 |
+
`E₁`, `E₂`, …, `E_N`, where N is the number of elements in the pack
|
| 150 |
+
expansion parameters. Each `Eᵢ` is generated by instantiating the
|
| 151 |
+
pattern and replacing each pack expansion parameter with its iᵗʰ
|
| 152 |
+
element. Such an element, in the context of the instantiation, is
|
| 153 |
+
interpreted as follows:
|
|
|
|
| 154 |
|
| 155 |
+
- if the pack is a template parameter pack, the element is an
|
| 156 |
+
*id-expression* (for a non-type template parameter pack), a
|
| 157 |
+
*typedef-name* (for a type template parameter pack declared without
|
| 158 |
+
`template`), or a *template-name* (for a type template parameter pack
|
| 159 |
+
declared with `template`), designating the iᵗʰ corresponding type or
|
| 160 |
+
value template argument;
|
| 161 |
- if the pack is a function parameter pack, the element is an
|
| 162 |
*id-expression* designating the iᵗʰ function parameter that resulted
|
| 163 |
from instantiation of the function parameter pack declaration;
|
| 164 |
otherwise
|
| 165 |
- if the pack is an *init-capture* pack, the element is an
|
| 166 |
*id-expression* designating the variable introduced by the iᵗʰ
|
| 167 |
*init-capture* that resulted from instantiation of the *init-capture*
|
| 168 |
+
pack declaration.
|
| 169 |
|
| 170 |
+
When N is zero, the instantiation of a pack expansion does not alter the
|
| 171 |
+
syntactic interpretation of the enclosing construct, even in cases where
|
| 172 |
+
omitting the pack expansion entirely would otherwise be ill-formed or
|
| 173 |
+
would result in an ambiguity in the grammar.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
|
| 175 |
The instantiation of a `sizeof...` expression [[expr.sizeof]] produces
|
| 176 |
+
an integral constant with value N.
|
|
|
|
| 177 |
|
| 178 |
+
The instantiation of a *fold-expression* [[expr.prim.fold]] produces:
|
| 179 |
|
| 180 |
+
- `(` `((`E₁ *op* E₂`)` *op* ⋯`)` *op* $\mathtt{E}_N$ `)` for a unary
|
| 181 |
+
left fold,
|
| 182 |
+
- `(` E₁ *op* `(`⋯ *op* `(`$\mathtt{E}_{N-1}$ *op* $\mathtt{E}_N$`))`
|
| 183 |
+
`)` for a unary right fold,
|
| 184 |
+
- `(` `(((`E *op* E₁`)` *op* E₂`)` *op* ⋯`)` *op* $\mathtt{E}_N$ `)` for
|
| 185 |
+
a binary left fold, and
|
| 186 |
+
- `(` E₁ *op* `(`⋯ *op* `(`$\mathtt{E}_{N-1}$ *op* `(`$\mathtt{E}_{N}$
|
| 187 |
+
*op* E`)))` `)` for a binary right fold.
|
| 188 |
|
| 189 |
+
In each case, *op* is the *fold-operator*. For a binary fold, E is
|
| 190 |
+
generated by instantiating the *cast-expression* that did not contain an
|
| 191 |
+
unexpanded pack.
|
|
|
|
|
|
|
|
|
|
| 192 |
|
| 193 |
+
[*Example 6*:
|
| 194 |
|
| 195 |
``` cpp
|
| 196 |
template<typename ...Args>
|
| 197 |
bool all(Args ...args) { return (... && args); }
|
| 198 |
|
|
|
|
| 202 |
Within the instantiation of `all`, the returned expression expands to
|
| 203 |
`((true && true) && true) && false`, which evaluates to `false`.
|
| 204 |
|
| 205 |
— *end example*]
|
| 206 |
|
| 207 |
+
If N is zero for a unary fold, the value of the expression is shown in
|
| 208 |
+
[[temp.fold.empty]]; if the operator is not listed in
|
| 209 |
[[temp.fold.empty]], the instantiation is ill-formed.
|
| 210 |
|
| 211 |
**Table: Value of folding empty sequences** <a id="temp.fold.empty">[temp.fold.empty]</a>
|
| 212 |
|
| 213 |
| Operator | Value when pack is empty |
|
|
|
|
| 215 |
| `&&` | `true` |
|
| 216 |
| `||` | `false` |
|
| 217 |
| `,` | `void()` |
|
| 218 |
|
| 219 |
|
| 220 |
+
The instantiation of any other pack expansion produces a list of
|
| 221 |
+
elements `E₁`, `E₂`, …, `E_N`.
|
| 222 |
+
|
| 223 |
+
[*Note 1*: The variety of list varies with the context:
|
| 224 |
+
*expression-list*, *base-specifier-list*, *template-argument-list*,
|
| 225 |
+
etc. — *end note*]
|
| 226 |
+
|
| 227 |
+
When N is zero, the instantiation of the expansion produces an empty
|
| 228 |
+
list.
|
| 229 |
+
|
| 230 |
+
[*Example 7*:
|
| 231 |
+
|
| 232 |
+
``` cpp
|
| 233 |
+
template<class... T> struct X : T... { };
|
| 234 |
+
template<class... T> void f(T... values) {
|
| 235 |
+
X<T...> x(values...);
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
template void f<>(); // OK, X<> has no base classes
|
| 239 |
+
// x is a variable of type X<> that is value-initialized
|
| 240 |
+
```
|
| 241 |
+
|
| 242 |
+
— *end example*]
|
| 243 |
+
|