From Jason Turner

[dcl.init.ref]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpp_1x62fm/{from.md → to.md} +92 -58
tmp/tmpp_1x62fm/{from.md → to.md} RENAMED
@@ -1,13 +1,14 @@
1
  ### References <a id="dcl.init.ref">[[dcl.init.ref]]</a>
2
 
3
- A variable declared to be a `T&` or `T&&`, that is, “reference to type
4
- `T`” ([[dcl.ref]]), shall be initialized by an object, or function, of
5
- type `T` or by an object that can be converted into a `T`.
 
6
 
7
  ``` cpp
8
- int g(int);
9
  void f() {
10
  int i;
11
  int& r = i; // r refers to i
12
  r = 1; // the value of i becomes 1
13
  int* p = &r; // p points to i
@@ -18,56 +19,75 @@ void f() {
18
  int (&ra)[3] = a; // ra refers to the array a
19
  ra[1] = i; // modifies a[1]
20
  }
21
  ```
22
 
 
 
23
  A reference cannot be changed to refer to another object after
24
- initialization. Note that initialization of a reference is treated very
25
- differently from assignment to it. Argument passing ([[expr.call]]) and
26
- function value return ([[stmt.return]]) are initializations.
 
 
 
 
27
 
28
  The initializer can be omitted for a reference only in a parameter
29
  declaration ([[dcl.fct]]), in the declaration of a function return
30
  type, in the declaration of a class member within its class definition (
31
  [[class.mem]]), and where the `extern` specifier is explicitly used.
32
 
 
 
33
  ``` cpp
34
  int& r1; // error: initializer missing
35
  extern int& r2; // OK
36
  ```
37
 
38
- Given types “ `T1`” and “ `T2`,” “ `T1`” is to “ `T2`” if `T1` is the
39
- same type as `T2`, or `T1` is a base class of `T2`. “ `T1`” is with “
40
- `T2`” if `T1` is reference-related to `T2` and *cv1* is the same
41
- cv-qualification as, or greater cv-qualification than, *cv2*. In all
42
- cases where the reference-related or reference-compatible relationship
43
- of two types is used to establish the validity of a reference binding,
44
- and `T1` is a base class of `T2`, a program that necessitates such a
45
- binding is ill-formed if `T1` is an inaccessible (Clause 
46
- [[class.access]]) or ambiguous ([[class.member.lookup]]) base class of
47
- `T2`.
 
 
 
 
 
 
 
 
48
 
49
  A reference to type “*cv1* `T1`” is initialized by an expression of type
50
  “*cv2* `T2`” as follows:
51
 
52
  - If the reference is an lvalue reference and the initializer expression
53
- - is an lvalue (but is not a bit-field), and “ `T1`” is
54
- reference-compatible with “ `T2`,” or
55
  - has a class type (i.e., `T2` is a class type), where `T1` is not
56
  reference-related to `T2`, and can be converted to an lvalue of type
57
- “ `T3`,” where “ `T1`” is reference-compatible with “ `T3`”[^16]
58
- (this conversion is selected by enumerating the applicable
59
- conversion functions ([[over.match.ref]]) and choosing the best one
60
- through overload resolution ([[over.match]])),
61
 
62
  then the reference is bound to the initializer expression lvalue in
63
  the first case and to the lvalue result of the conversion in the
64
  second case (or, in either case, to the appropriate base class
65
- subobject of the object). The usual lvalue-to-rvalue ([[conv.lval]]),
 
66
  array-to-pointer ([[conv.array]]), and function-to-pointer (
67
  [[conv.func]]) standard conversions are not needed, and therefore are
68
- suppressed, when such direct bindings to lvalues are done.
 
 
69
  ``` cpp
70
  double d = 2.0;
71
  double& rd = d; // rd refers to d
72
  const double& rcd = d; // rcd refers to d
73
 
@@ -75,36 +95,39 @@ A reference to type “*cv1* `T1`” is initialized by an expression of type
75
  struct B : A { operator int&(); } b;
76
  A& ra = b; // ra refers to A subobject in b
77
  const A& rca = b; // rca refers to A subobject in b
78
  int& ir = B(); // ir refers to the result of B::operator int&
79
  ```
 
 
80
  - Otherwise, the reference shall be an lvalue reference to a
81
  non-volatile const type (i.e., *cv1* shall be `const`), or the
82
  reference shall be an rvalue reference.
 
83
  ``` cpp
84
  double& rd2 = 2.0; // error: not an lvalue and reference not const
85
  int i = 2;
86
  double& rd3 = i; // error: type mismatch and reference not const
87
  ```
88
 
 
89
  - If the initializer expression
90
- - is an xvalue (but not a bit-field), class prvalue, array prvalue
91
- or function lvalue and “*cv1* `T1`” is reference-compatible with
92
- “*cv2* `T2`”, or
93
  - has a class type (i.e., `T2` is a class type), where `T1` is not
94
- reference-related to `T2`, and can be converted to an xvalue,
95
- class prvalue, or function lvalue of type “*cv3* `T3`”, where
96
- “*cv1* `T1`” is reference-compatible with “*cv3* `T3`” (see 
97
- [[over.match.ref]]),
98
 
99
- then the reference is bound to the value of the initializer
100
- expression in the first case and to the result of the conversion in
101
- the second case (or, in either case, to an appropriate base class
102
- subobject). In the second case, if the reference is an rvalue
103
- reference and the second standard conversion sequence of the
104
- user-defined conversion sequence includes an lvalue-to-rvalue
105
- conversion, the program is ill-formed.
 
106
  ``` cpp
107
  struct A { };
108
  struct B : A { } b;
109
  extern B f();
110
  const A& rca2 = f(); // bound to the A subobject of the B rvalue.
@@ -115,55 +138,66 @@ A reference to type “*cv1* `T1`” is initialized by an expression of type
115
  } x;
116
  const A& r = x; // bound to the A subobject of the result of the conversion
117
  int i2 = 42;
118
  int&& rri = static_cast<int&&>(i2); // bound directly to i2
119
  B&& rrb = x; // bound directly to the result of operator B
120
- int&& rri2 = X(); // error: lvalue-to-rvalue conversion applied to the
121
- // result of operator int&
122
  ```
 
 
123
  - Otherwise:
124
- - If `T1` is a class type, user-defined conversions are considered
125
- using the rules for copy-initialization of an object of type
126
- `T1`” by user-defined conversion ([[dcl.init]],
127
- [[over.match.copy]]); the program is ill-formed if the
 
128
  corresponding non-reference copy-initialization would be
129
  ill-formed. The result of the call to the conversion function, as
130
  described for the non-reference copy-initialization, is then used
131
- to direct-initialize the reference. The program is ill-formed if
132
- the direct-initialization does not result in a direct binding or
133
- if it involves a user-defined conversion.
134
- - If `T1` is a non-class type, a temporary of type `T1`” is
135
- created and copy-initialized ([[dcl.init]]) from the initializer
136
- expression. The reference is then bound to the temporary.
137
 
138
  If `T1` is reference-related to `T2`:
139
  - *cv1* shall be the same cv-qualification as, or greater
140
  cv-qualification than, *cv2*; and
141
  - if the reference is an rvalue reference, the initializer
142
  expression shall not be an lvalue.
143
 
 
144
  ``` cpp
145
  struct Banana { };
146
  struct Enigma { operator const Banana(); };
 
147
  void enigmatic() {
148
  typedef const Banana ConstBanana;
149
  Banana &&banana1 = ConstBanana(); // ill-formed
150
  Banana &&banana2 = Enigma(); // ill-formed
 
151
  }
152
 
153
  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
154
  double&& rrd = 2; // rrd refers to temporary with value 2.0
155
  const volatile int cvi = 1;
156
- const int& r2 = cvi; // error: type qualifiers dropped
 
 
 
157
  double d2 = 1.0;
158
- double&& rrd2 = d2; // error: copying lvalue of related type
 
 
159
  int i3 = 2;
160
  double&& rrd3 = i3; // rrd3 refers to temporary with value 2.0
161
  ```
162
 
163
- In all cases except the last (i.e., creating and initializing a
164
- temporary from the initializer expression), the reference is said to
165
- *bind directly* to the initializer expression.
166
 
167
- [[class.temporary]] describes the lifetime of temporaries bound to
168
- references.
 
 
 
 
169
 
 
1
  ### References <a id="dcl.init.ref">[[dcl.init.ref]]</a>
2
 
3
+ A variable whose declared type is “reference to type `T`” ([[dcl.ref]])
4
+ shall be initialized.
5
+
6
+ [*Example 1*:
7
 
8
  ``` cpp
9
+ int g(int) noexcept;
10
  void f() {
11
  int i;
12
  int& r = i; // r refers to i
13
  r = 1; // the value of i becomes 1
14
  int* p = &r; // p points to i
 
19
  int (&ra)[3] = a; // ra refers to the array a
20
  ra[1] = i; // modifies a[1]
21
  }
22
  ```
23
 
24
+ — *end example*]
25
+
26
  A reference cannot be changed to refer to another object after
27
+ initialization.
28
+
29
+ [*Note 1*: Assignment to a reference assigns to the object referred to
30
+ by the reference ([[expr.ass]]). — *end note*]
31
+
32
+ Argument passing ([[expr.call]]) and function value return (
33
+ [[stmt.return]]) are initializations.
34
 
35
  The initializer can be omitted for a reference only in a parameter
36
  declaration ([[dcl.fct]]), in the declaration of a function return
37
  type, in the declaration of a class member within its class definition (
38
  [[class.mem]]), and where the `extern` specifier is explicitly used.
39
 
40
+ [*Example 2*:
41
+
42
  ``` cpp
43
  int& r1; // error: initializer missing
44
  extern int& r2; // OK
45
  ```
46
 
47
+ *end example*]
48
+
49
+ Given types “*cv1* `T1` and “*cv2* `T2`”, *cv1* `T1`” is
50
+ *reference-related* to “*cv2* `T2`” if `T1` is the same type as `T2`, or
51
+ `T1` is a base class of `T2`. “*cv1* `T1`” is *reference-compatible*
52
+ with “*cv2* `T2`” if
53
+
54
+ - `T1` is reference-related to `T2`, or
55
+ - `T2` is “`noexcept` function” and `T1` is “function”, where the
56
+ function types are otherwise the same,
57
+
58
+ and *cv1* is the same cv-qualification as, or greater cv-qualification
59
+ than, *cv2*. In all cases where the reference-related or
60
+ reference-compatible relationship of two types is used to establish the
61
+ validity of a reference binding, and `T1` is a base class of `T2`, a
62
+ program that necessitates such a binding is ill-formed if `T1` is an
63
+ inaccessible (Clause  [[class.access]]) or ambiguous (
64
+ [[class.member.lookup]]) base class of `T2`.
65
 
66
  A reference to type “*cv1* `T1`” is initialized by an expression of type
67
  “*cv2* `T2`” as follows:
68
 
69
  - If the reference is an lvalue reference and the initializer expression
70
+ - is an lvalue (but is not a bit-field), and “*cv1* `T1`” is
71
+ reference-compatible with “*cv2* `T2`”, or
72
  - has a class type (i.e., `T2` is a class type), where `T1` is not
73
  reference-related to `T2`, and can be converted to an lvalue of type
74
+ *cv3* `T3`”, where “*cv1* `T1`” is reference-compatible with “*cv3*
75
+ `T3`”[^14] (this conversion is selected by enumerating the
76
+ applicable conversion functions ([[over.match.ref]]) and choosing
77
+ the best one through overload resolution ([[over.match]])),
78
 
79
  then the reference is bound to the initializer expression lvalue in
80
  the first case and to the lvalue result of the conversion in the
81
  second case (or, in either case, to the appropriate base class
82
+ subobject of the object).
83
+ \[*Note 2*: The usual lvalue-to-rvalue ([[conv.lval]]),
84
  array-to-pointer ([[conv.array]]), and function-to-pointer (
85
  [[conv.func]]) standard conversions are not needed, and therefore are
86
+ suppressed, when such direct bindings to lvalues are
87
+ done. — *end note*]
88
+ \[*Example 3*:
89
  ``` cpp
90
  double d = 2.0;
91
  double& rd = d; // rd refers to d
92
  const double& rcd = d; // rcd refers to d
93
 
 
95
  struct B : A { operator int&(); } b;
96
  A& ra = b; // ra refers to A subobject in b
97
  const A& rca = b; // rca refers to A subobject in b
98
  int& ir = B(); // ir refers to the result of B::operator int&
99
  ```
100
+
101
+ — *end example*]
102
  - Otherwise, the reference shall be an lvalue reference to a
103
  non-volatile const type (i.e., *cv1* shall be `const`), or the
104
  reference shall be an rvalue reference.
105
+ \[*Example 4*:
106
  ``` cpp
107
  double& rd2 = 2.0; // error: not an lvalue and reference not const
108
  int i = 2;
109
  double& rd3 = i; // error: type mismatch and reference not const
110
  ```
111
 
112
+ — *end example*]
113
  - If the initializer expression
114
+ - is an rvalue (but not a bit-field) or function lvalue and “*cv1*
115
+ `T1`” is reference-compatible with “*cv2* `T2`”, or
 
116
  - has a class type (i.e., `T2` is a class type), where `T1` is not
117
+ reference-related to `T2`, and can be converted to an rvalue or
118
+ function lvalue of type “*cv3* `T3`”, where “*cv1* `T1`” is
119
+ reference-compatible with “*cv3* `T3`” (see  [[over.match.ref]]),
 
120
 
121
+ then the value of the initializer expression in the first case and
122
+ the result of the conversion in the second case is called the
123
+ converted initializer. If the converted initializer is a prvalue,
124
+ its type `T4` is adjusted to type “*cv1* `T4`” ([[conv.qual]]) and
125
+ the temporary materialization conversion ([[conv.rval]]) is
126
+ applied. In any case, the reference is bound to the resulting
127
+ glvalue (or to an appropriate base class subobject).
128
+ \[*Example 5*:
129
  ``` cpp
130
  struct A { };
131
  struct B : A { } b;
132
  extern B f();
133
  const A& rca2 = f(); // bound to the A subobject of the B rvalue.
 
138
  } x;
139
  const A& r = x; // bound to the A subobject of the result of the conversion
140
  int i2 = 42;
141
  int&& rri = static_cast<int&&>(i2); // bound directly to i2
142
  B&& rrb = x; // bound directly to the result of operator B
 
 
143
  ```
144
+
145
+ — *end example*]
146
  - Otherwise:
147
+ - If `T1` or `T2` is a class type and `T1` is not reference-related
148
+ to `T2`, user-defined conversions are considered using the rules
149
+ for copy-initialization of an object of type “*cv1* `T1`” by
150
+ user-defined conversion ([[dcl.init]], [[over.match.copy]],
151
+ [[over.match.conv]]); the program is ill-formed if the
152
  corresponding non-reference copy-initialization would be
153
  ill-formed. The result of the call to the conversion function, as
154
  described for the non-reference copy-initialization, is then used
155
+ to direct-initialize the reference. For this
156
+ direct-initialization, user-defined conversions are not
157
+ considered.
158
+ - Otherwise, the initializer expression is implicitly converted to a
159
+ prvalue of type “*cv1* `T1`”. The temporary materialization
160
+ conversion is applied and the reference is bound to the result.
161
 
162
  If `T1` is reference-related to `T2`:
163
  - *cv1* shall be the same cv-qualification as, or greater
164
  cv-qualification than, *cv2*; and
165
  - if the reference is an rvalue reference, the initializer
166
  expression shall not be an lvalue.
167
 
168
+ \[*Example 6*:
169
  ``` cpp
170
  struct Banana { };
171
  struct Enigma { operator const Banana(); };
172
+ struct Alaska { operator Banana&(); };
173
  void enigmatic() {
174
  typedef const Banana ConstBanana;
175
  Banana &&banana1 = ConstBanana(); // ill-formed
176
  Banana &&banana2 = Enigma(); // ill-formed
177
+ Banana &&banana3 = Alaska(); // ill-formed
178
  }
179
 
180
  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
181
  double&& rrd = 2; // rrd refers to temporary with value 2.0
182
  const volatile int cvi = 1;
183
+ const int& r2 = cvi; // error: cv-qualifier dropped
184
+ struct A { operator volatile int&(); } a;
185
+ const int& r3 = a; // error: cv-qualifier dropped
186
+ // from result of conversion function
187
  double d2 = 1.0;
188
+ double&& rrd2 = d2; // error: initializer is lvalue of related type
189
+ struct X { operator int&(); };
190
+ int&& rri2 = X(); // error: result of conversion function is lvalue of related type
191
  int i3 = 2;
192
  double&& rrd3 = i3; // rrd3 refers to temporary with value 2.0
193
  ```
194
 
195
+ *end example*]
 
 
196
 
197
+ In all cases except the last (i.e., implicitly converting the
198
+ initializer expression to the underlying type of the reference), the
199
+ reference is said to *bind directly* to the initializer expression.
200
+
201
+ [*Note 3*: [[class.temporary]] describes the lifetime of temporaries
202
+ bound to references. — *end note*]
203