From Jason Turner

[dcl.init.ref]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpis30l8kp/{from.md → to.md} +49 -57
tmp/tmpis30l8kp/{from.md → to.md} RENAMED
@@ -1,8 +1,8 @@
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
@@ -25,19 +25,19 @@ void f() {
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
@@ -45,48 +45,41 @@ 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
@@ -97,36 +90,36 @@ A reference to type “*cv1* `T1`” is initialized by an expression of type
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();
@@ -142,41 +135,40 @@ A reference to type “*cv1* `T1`” is initialized by an expression of type
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;
@@ -193,11 +185,11 @@ A reference to type “*cv1* `T1`” is initialized by an expression of type
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
 
 
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
 
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 [[stmt.return]]
33
+ 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 type,
37
+ 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
 
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 similar [[conv.qual]] to
51
+ `T2`, or `T1` is a base class of `T2`. “*cv1* `T1`” is
52
+ *reference-compatible* with “*cv2* `T2`” if a prvalue of type “pointer
53
+ to *cv2* `T2`” can be converted to the type “pointer to *cv1* `T1`” via
54
+ a standard conversion sequence [[conv]]. In all cases where the
 
 
 
 
 
55
  reference-compatible relationship of two types is used to establish the
56
+ validity of a reference binding and the standard conversion sequence
57
+ would be ill-formed, a program that necessitates such a binding is
58
+ ill-formed.
 
59
 
60
  A reference to type “*cv1* `T1`” is initialized by an expression of type
61
  “*cv2* `T2`” as follows:
62
 
63
  - If the reference is an lvalue reference and the initializer expression
64
  - is an lvalue (but is not a bit-field), and “*cv1* `T1`” is
65
  reference-compatible with “*cv2* `T2`”, or
66
  - has a class type (i.e., `T2` is a class type), where `T1` is not
67
  reference-related to `T2`, and can be converted to an lvalue of type
68
  “*cv3* `T3`”, where “*cv1* `T1`” is reference-compatible with “*cv3*
69
+ `T3`”[^7] (this conversion is selected by enumerating the applicable
70
+ conversion functions [[over.match.ref]] and choosing the best one
71
+ through overload resolution [[over.match]]),
72
 
73
  then the reference is bound to the initializer expression lvalue in
74
  the first case and to the lvalue result of the conversion in the
75
  second case (or, in either case, to the appropriate base class
76
  subobject of the object).
77
+ \[*Note 2*: The usual lvalue-to-rvalue [[conv.lval]], array-to-pointer
78
+ [[conv.array]], and function-to-pointer [[conv.func]] standard
79
+ conversions are not needed, and therefore are suppressed, when such
80
+ direct bindings to lvalues are done. — *end note*]
 
81
  \[*Example 3*:
82
  ``` cpp
83
  double d = 2.0;
84
  double& rd = d; // rd refers to d
85
  const double& rcd = d; // rcd refers to d
 
90
  const A& rca = b; // rca refers to A subobject in b
91
  int& ir = B(); // ir refers to the result of B::operator int&
92
  ```
93
 
94
  — *end example*]
95
+ - Otherwise, if the reference is an lvalue reference to a type that is
96
+ not const-qualified or is volatile-qualified, the program is
97
+ ill-formed.
98
  \[*Example 4*:
99
  ``` cpp
100
  double& rd2 = 2.0; // error: not an lvalue and reference not const
101
  int i = 2;
102
  double& rd3 = i; // error: type mismatch and reference not const
103
  ```
104
 
105
  — *end example*]
106
+ - Otherwise, if the initializer expression
107
  - is an rvalue (but not a bit-field) or function lvalue and “*cv1*
108
  `T1`” is reference-compatible with “*cv2* `T2`”, or
109
  - has a class type (i.e., `T2` is a class type), where `T1` is not
110
  reference-related to `T2`, and can be converted to an rvalue or
111
  function lvalue of type “*cv3* `T3`”, where “*cv1* `T1`” is
112
  reference-compatible with “*cv3* `T3`” (see  [[over.match.ref]]),
113
 
114
+ then the value of the initializer expression in the first case and the
115
+ result of the conversion in the second case is called the converted
116
+ initializer. If the converted initializer is a prvalue, its type `T4`
117
+ is adjusted to type “*cv1* `T4`” [[conv.qual]] and the temporary
118
+ materialization conversion [[conv.rval]] is applied. In any case, the
119
+ reference is bound to the resulting glvalue (or to an appropriate base
120
+ class subobject).
121
  \[*Example 5*:
122
  ``` cpp
123
  struct A { };
124
  struct B : A { } b;
125
  extern B f();
 
135
  B&& rrb = x; // bound directly to the result of operator B
136
  ```
137
 
138
  — *end example*]
139
  - Otherwise:
140
+ - If `T1` or `T2` is a class type and `T1` is not reference-related to
141
+ `T2`, user-defined conversions are considered using the rules for
142
+ copy-initialization of an object of type “*cv1* `T1`” by
143
  user-defined conversion ([[dcl.init]], [[over.match.copy]],
144
+ [[over.match.conv]]); the program is ill-formed if the corresponding
145
+ non-reference copy-initialization would be ill-formed. The result of
146
+ the call to the conversion function, as described for the
147
+ non-reference copy-initialization, is then used to direct-initialize
148
+ the reference. For this direct-initialization, user-defined
149
+ conversions are not considered.
 
150
  - Otherwise, the initializer expression is implicitly converted to a
151
  prvalue of type “*cv1* `T1`”. The temporary materialization
152
  conversion is applied and the reference is bound to the result.
153
 
154
  If `T1` is reference-related to `T2`:
155
  - *cv1* shall be the same cv-qualification as, or greater
156
  cv-qualification than, *cv2*; and
157
+ - if the reference is an rvalue reference, the initializer expression
158
+ shall not be an lvalue.
159
 
160
  \[*Example 6*:
161
  ``` cpp
162
  struct Banana { };
163
  struct Enigma { operator const Banana(); };
164
  struct Alaska { operator Banana&(); };
165
  void enigmatic() {
166
  typedef const Banana ConstBanana;
167
+ Banana &&banana1 = ConstBanana(); // error
168
+ Banana &&banana2 = Enigma(); // error
169
+ Banana &&banana3 = Alaska(); // error
170
  }
171
 
172
  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
173
  double&& rrd = 2; // rrd refers to temporary with value 2.0
174
  const volatile int cvi = 1;
 
185
  ```
186
 
187
  — *end example*]
188
 
189
  In all cases except the last (i.e., implicitly converting the
190
+ initializer expression to the referenced type), the reference is said to
191
+ *bind directly* to the initializer expression.
192
 
193
  [*Note 3*: [[class.temporary]] describes the lifetime of temporaries
194
  bound to references. — *end note*]
195