From Jason Turner

[dcl.struct.bind]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpl2_xlot5/{from.md → to.md} +94 -35
tmp/tmpl2_xlot5/{from.md → to.md} RENAMED
@@ -1,16 +1,21 @@
1
  ## Structured binding declarations <a id="dcl.struct.bind">[[dcl.struct.bind]]</a>
2
 
3
  A structured binding declaration introduces the *identifier*s `v₀`,
4
- `v₁`, `v₂`, … of the *identifier-list* as names of *structured
5
- binding*s. Let cv denote the *cv-qualifier*s in the *decl-specifier-seq*
6
- and *S* consist of the *storage-class-specifier*s of the
7
- *decl-specifier-seq* (if any). A cv that includes `volatile` is
8
- deprecated; see  [[depr.volatile.type]]. First, a variable with a unique
9
- name *`e`* is introduced. If the *assignment-expression* in the
10
- *initializer* has array type *cv1* `A` and no *ref-qualifier* is
11
- present, *`e`* is defined by
 
 
 
 
 
12
 
13
  ``` bnf
14
  attribute-specifier-seqₒₚₜ *S* cv 'A' e ';'
15
  ```
16
 
@@ -27,44 +32,94 @@ the parts of the declaration other than the *declarator-id* are taken
27
  from the corresponding structured binding declaration. The type of the
28
  *id-expression* *`e`* is called `E`.
29
 
30
  [*Note 1*: `E` is never a reference type [[expr.prop]]. — *end note*]
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  If the *initializer* refers to one of the names introduced by the
33
  structured binding declaration, the program is ill-formed.
34
 
35
- If `E` is an array type with element type `T`, the number of elements in
36
- the *identifier-list* shall be equal to the number of elements of `E`.
37
- Each `vᵢ` is the name of an lvalue that refers to the element i of the
38
- array and whose type is `T`; the referenced type is `T`.
 
39
 
40
- [*Note 2*: The top-level cv-qualifiers of `T` are cv. — *end note*]
41
 
42
- [*Example 1*:
43
 
44
  ``` cpp
45
  auto f() -> int(&)[2];
46
  auto [ x, y ] = f(); // x and y refer to elements in a copy of the array return value
47
  auto& [ xr, yr ] = f(); // xr and yr refer to elements in the array referred to by f's return value
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  ```
49
 
50
  — *end example*]
51
 
52
  Otherwise, if the *qualified-id* `std::tuple_size<E>` names a complete
53
  class type with a member named `value`, the expression
54
  `std::tuple_size<E>::value` shall be a well-formed integral constant
55
- expression and the number of elements in the *identifier-list* shall be
56
- equal to the value of that expression. Let `i` be an index prvalue of
57
- type `std::size_t` corresponding to `vᵢ`. If a search for the name `get`
58
- in the scope of `E` [[class.member.lookup]] finds at least one
59
- declaration that is a function template whose first template parameter
60
- is a non-type parameter, the initializer is `e.get<i>()`. Otherwise, the
61
- initializer is `get<i>(e)`, where `get` undergoes argument-dependent
62
- lookup [[basic.lookup.argdep]]. In either case, `get<i>` is interpreted
63
- as a *template-id*.
64
 
65
- [*Note 3*: Ordinary unqualified lookup [[basic.lookup.unqual]] is not
66
  performed. — *end note*]
67
 
68
  In either case, *`e`* is an lvalue if the type of the entity *`e`* is an
69
  lvalue reference and an xvalue otherwise. Given the type `Tᵢ` designated
70
  by `std::tuple_element<i, E>::type` and the type `Uᵢ` designated by
@@ -74,26 +129,30 @@ are introduced with unique names `rᵢ` as follows:
74
 
75
  ``` bnf
76
  *S* 'Uᵢ rᵢ =' initializer ';'
77
  ```
78
 
79
- Each `vᵢ` is the name of an lvalue of type `Tᵢ` that refers to the
80
- object bound to `rᵢ`; the referenced type is `Tᵢ`.
 
 
 
 
81
 
82
  Otherwise, all of `E`’s non-static data members shall be direct members
83
  of `E` or of the same base class of `E`, well-formed when named as
84
  `e.name` in the context of the structured binding, `E` shall not have an
85
- anonymous union member, and the number of elements in the
86
- *identifier-list* shall be equal to the number of non-static data
87
- members of `E`. Designating the non-static data members of `E` as `m₀`,
88
- `m₁`, `m₂`, … (in declaration order), each `vᵢ` is the name of an lvalue
89
- that refers to the member `m`ᵢ of *`e`* and whose type is that of `e.mᵢ`
90
- [[expr.ref]]; the referenced type is the declared type of `mᵢ` if that
91
- type is a reference type, or the type of `e.mᵢ` otherwise. The lvalue is
92
- a bit-field if that member is a bit-field.
93
 
94
- [*Example 2*:
95
 
96
  ``` cpp
97
  struct S { mutable int x1 : 2; volatile double y1; };
98
  S f();
99
  const auto [ x, y ] = f();
 
1
  ## Structured binding declarations <a id="dcl.struct.bind">[[dcl.struct.bind]]</a>
2
 
3
  A structured binding declaration introduces the *identifier*s `v₀`,
4
+ `v₁`, `v₂`, …, `v_N-1` of the *sb-identifier-list* as names. An
5
+ *sb-identifier* that contains an ellipsis introduces a structured
6
+ binding pack [[temp.variadic]]. A *structured binding* is either an
7
+ *sb-identifier* that does not contain an ellipsis or an element of a
8
+ structured binding pack. The optional *attribute-specifier-seq* of an
9
+ *sb-identifier* appertains to the associated structured bindings. Let cv
10
+ denote the *cv-qualifier*s in the *decl-specifier-seq* and *S* consist
11
+ of each *decl-specifier* of the *decl-specifier-seq* that is
12
+ `constexpr`, `constinit`, or a *storage-class-specifier*. A cv that
13
+ includes `volatile` is deprecated; see  [[depr.volatile.type]]. First, a
14
+ variable with a unique name *`e`* is introduced. If the
15
+ *assignment-expression* in the *initializer* has array type *cv1* `A`
16
+ and no *ref-qualifier* is present, *`e`* is defined by
17
 
18
  ``` bnf
19
  attribute-specifier-seqₒₚₜ *S* cv 'A' e ';'
20
  ```
21
 
 
32
  from the corresponding structured binding declaration. The type of the
33
  *id-expression* *`e`* is called `E`.
34
 
35
  [*Note 1*: `E` is never a reference type [[expr.prop]]. — *end note*]
36
 
37
+ The *structured binding size* of `E`, as defined below, is the number of
38
+ structured bindings that need to be introduced by the structured binding
39
+ declaration. If there is no structured binding pack, then the number of
40
+ elements in the *sb-identifier-list* shall be equal to the structured
41
+ binding size of `E`. Otherwise, the number of non-pack elements shall be
42
+ no more than the structured binding size of `E`; the number of elements
43
+ of the structured binding pack is the structured binding size of `E`
44
+ less the number of non-pack elements in the *sb-identifier-list*.
45
+
46
+ Let $\textrm{SB}_i$ denote the $i^\textrm{th}$ structured binding in the
47
+ structured binding declaration after expanding the structured binding
48
+ pack, if any.
49
+
50
+ [*Note 2*: If there is no structured binding pack, then $\textrm{SB}_i$
51
+ denotes `vᵢ`. — *end note*]
52
+
53
+ [*Example 1*:
54
+
55
+ ``` cpp
56
+ struct C { int x, y, z; };
57
+
58
+ template<class T>
59
+ void now_i_know_my() {
60
+ auto [a, b, c] = C(); // OK, $SB_0$ is a, $SB_1$ is b, and $SB_2$ is c
61
+ auto [d, ...e] = C(); // OK, $SB_0$ is d, the pack e (`v`_1) contains two structured bindings: $SB_1$ and $SB_2$
62
+ auto [...f, g] = C(); // OK, the pack f (`v`_0) contains two structured bindings: $SB_0$ and $SB_1$, and $SB_2$ is g
63
+ auto [h, i, j, ...k] = C(); // OK, the pack k is empty
64
+ auto [l, m, n, o, ...p] = C(); // error: structured binding size is too small
65
+ }
66
+ ```
67
+
68
+ — *end example*]
69
+
70
+ If a structured binding declaration appears as a *condition*, the
71
+ decision variable [[stmt.pre]] of the condition is *`e`*.
72
+
73
  If the *initializer* refers to one of the names introduced by the
74
  structured binding declaration, the program is ill-formed.
75
 
76
+ `E` shall not be an array type of unknown bound. If `E` is any other
77
+ array type with element type `T`, the structured binding size of `E` is
78
+ equal to the number of elements of `E`. Each $\textrm{SB}_i$ is the name
79
+ of an lvalue that refers to the element i of the array and whose type is
80
+ `T`; the referenced type is `T`.
81
 
82
+ [*Note 3*: The top-level cv-qualifiers of `T` are cv. — *end note*]
83
 
84
+ [*Example 2*:
85
 
86
  ``` cpp
87
  auto f() -> int(&)[2];
88
  auto [ x, y ] = f(); // x and y refer to elements in a copy of the array return value
89
  auto& [ xr, yr ] = f(); // xr and yr refer to elements in the array referred to by f's return value
90
+
91
+ auto g() -> int(&)[4];
92
+
93
+ template<size_t N>
94
+ void h(int (&arr)[N]) {
95
+ auto [a, ...b, c] = arr; // a names the first element of the array, b is a pack referring to the second and
96
+ // third elements, and c names the fourth element
97
+ auto& [...e] = arr; // e is a pack referring to the four elements of the array
98
+ }
99
+
100
+ void call_h() {
101
+ h(g());
102
+ }
103
  ```
104
 
105
  — *end example*]
106
 
107
  Otherwise, if the *qualified-id* `std::tuple_size<E>` names a complete
108
  class type with a member named `value`, the expression
109
  `std::tuple_size<E>::value` shall be a well-formed integral constant
110
+ expression and the structured binding size of `E` is equal to the value
111
+ of that expression. Let `i` be an index prvalue of type `std::size_t`
112
+ corresponding to `vᵢ`. If a search for the name `get` in the scope of
113
+ `E` [[class.member.lookup]] finds at least one declaration that is a
114
+ function template whose first template parameter is a constant template
115
+ parameter, the initializer is `e.get<i>()`. Otherwise, the initializer
116
+ is `get<i>(e)`, where `get` undergoes argument-dependent lookup
117
+ [[basic.lookup.argdep]]. In either case, `get<i>` is interpreted as a
118
+ *template-id*.
119
 
120
+ [*Note 4*: Ordinary unqualified lookup [[basic.lookup.unqual]] is not
121
  performed. — *end note*]
122
 
123
  In either case, *`e`* is an lvalue if the type of the entity *`e`* is an
124
  lvalue reference and an xvalue otherwise. Given the type `Tᵢ` designated
125
  by `std::tuple_element<i, E>::type` and the type `Uᵢ` designated by
 
129
 
130
  ``` bnf
131
  *S* 'Uᵢ rᵢ =' initializer ';'
132
  ```
133
 
134
+ Each $\textrm{SB}_i$ is the name of an lvalue of type `Tᵢ` that refers
135
+ to the object bound to `rᵢ`; the referenced type is `Tᵢ`. The
136
+ initialization of *`e`* and any conversion of *`e`* considered as a
137
+ decision variable [[stmt.pre]] is sequenced before the initialization of
138
+ any `rᵢ`. The initialization of each `rᵢ` is sequenced before the
139
+ initialization of any `rⱼ` where i < j.
140
 
141
  Otherwise, all of `E`’s non-static data members shall be direct members
142
  of `E` or of the same base class of `E`, well-formed when named as
143
  `e.name` in the context of the structured binding, `E` shall not have an
144
+ anonymous union member, and the structured binding size of `E` is equal
145
+ to the number of non-static data members of `E`. Designating the
146
+ non-static data members of `E` as `m₀`, `m₁`, `m₂`, … (in declaration
147
+ order), each $\textrm{SB}_i$ is the name of an lvalue that refers to the
148
+ member `m`ᵢ of *`e`* and whose type is that of `e.mᵢ` [[expr.ref]]; the
149
+ referenced type is the declared type of `mᵢ` if that type is a reference
150
+ type, or the type of `e.mᵢ` otherwise. The lvalue is a bit-field if that
151
+ member is a bit-field.
152
 
153
+ [*Example 3*:
154
 
155
  ``` cpp
156
  struct S { mutable int x1 : 2; volatile double y1; };
157
  S f();
158
  const auto [ x, y ] = f();