From Jason Turner

[temp.variadic]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3kt43a3n/{from.md → to.md} +95 -25
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* parameter packs in the pattern.
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 ...); // OK: first ``args'' expanded within h, second
107
- // ``args'' expanded within f
108
  }
109
  ```
110
 
111
- The instantiation of a pack expansion that is not a `sizeof...`
112
- expression produces a list
113
- $\mathtt{E}_1, \mathtt{E}_2, ..., \mathtt{E}_N$, where N is the number
114
- of elements in the pack expansion parameters. Each Eᵢ is generated by
115
- instantiating the pattern and replacing each pack expansion parameter
116
- with its ith element. Such an element, in the context of the
 
 
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. The variety of list
128
- varies with the context: *expression-list*, *base-specifier-list*,
129
- *template-argument-list*, etc. When N is zero, the instantiation of the
130
- expansion produces an empty list. Such an instantiation does not alter
131
- the syntactic interpretation of the enclosing construct, even in cases
132
- where omitting the list entirely would otherwise be ill-formed or would
133
- result in an ambiguity in the grammar.
 
 
 
 
 
 
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
+