From Jason Turner

[dcl.init.ref]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp45lsbrzb/{from.md → to.md} +48 -27
tmp/tmp45lsbrzb/{from.md → to.md} RENAMED
@@ -36,33 +36,30 @@ 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*. For
42
- purposes of overload resolution, cases for which *cv1* is greater
43
- cv-qualification than *cv2* are identified as
44
- *reference-compatible with added qualification* (see 
45
- [[over.ics.rank]]). In all cases where the reference-related or
46
- reference-compatible relationship of two types is used to establish the
47
- validity of a reference binding, and `T1` is a base class of `T2`, a
48
- program that necessitates such a binding is ill-formed if `T1` is an
49
- inaccessible (Clause  [[class.access]]) or ambiguous (
50
- [[class.member.lookup]]) base class of `T2`.
51
 
52
  A reference to type “*cv1* `T1`” is initialized by an expression of type
53
  “*cv2* `T2`” as follows:
54
 
55
  - If the reference is an lvalue reference and the initializer expression
56
  - is an lvalue (but is not a bit-field), and “ `T1`” is
57
  reference-compatible with “ `T2`,” or
58
  - has a class type (i.e., `T2` is a class type), where `T1` is not
59
- reference-related to `T2`, and can be implicitly converted to an
60
- lvalue of type “ `T3`,” where “ `T1`” is reference-compatible with “
61
- `T3`”[^18] (this conversion is selected by enumerating the
62
- applicable conversion functions ([[over.match.ref]]) and choosing
63
- the best one through overload resolution ([[over.match]])),
64
 
65
  then the reference is bound to the initializer expression lvalue in
66
  the first case and to the lvalue result of the conversion in the
67
  second case (or, in either case, to the appropriate base class
68
  subobject of the object). The usual lvalue-to-rvalue ([[conv.lval]]),
@@ -88,16 +85,18 @@ A reference to type “*cv1* `T1`” is initialized by an expression of type
88
  int i = 2;
89
  double& rd3 = i; // error: type mismatch and reference not const
90
  ```
91
 
92
  - If the initializer expression
93
- - is an xvalue, class prvalue, array prvalue or function lvalue and
94
- “*cv1* `T1`” is reference-compatible with “*cv2* `T2`”, or
 
95
  - has a class type (i.e., `T2` is a class type), where `T1` is not
96
- reference-related to `T2`, and can be implicitly converted to an
97
- xvalue, class prvalue, or function lvalue of type “*cv3* `T3`”,
98
- where “*cv1* `T1`” is reference-compatible with “*cv3* `T3`”,
 
99
 
100
  then the reference is bound to the value of the initializer
101
  expression in the first case and to the result of the conversion in
102
  the second case (or, in either case, to an appropriate base class
103
  subobject). In the second case, if the reference is an rvalue
@@ -119,18 +118,40 @@ A reference to type “*cv1* `T1`” is initialized by an expression of type
119
  int&& rri = static_cast<int&&>(i2); // bound directly to i2
120
  B&& rrb = x; // bound directly to the result of operator B
121
  int&& rri2 = X(); // error: lvalue-to-rvalue conversion applied to the
122
  // result of operator int&
123
  ```
124
- - Otherwise, a temporary of type “ `T1`” is created and initialized
125
- from the initializer expression using the rules for a non-reference
126
- copy-initialization ([[dcl.init]]). The reference is then bound to
127
- the temporary. If `T1` is reference-related to `T2`, *cv1* shall be
128
- the same cv-qualification as, or greater cv-qualification than,
129
- *cv2*. If `T1` is reference-related to `T2` and the reference is an
130
- rvalue reference, the initializer expression shall not be an lvalue.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  ``` cpp
 
 
 
 
 
 
 
 
132
  const double& rcd2 = 2; // rcd2 refers to temporary with value 2.0
133
  double&& rrd = 2; // rrd refers to temporary with value 2.0
134
  const volatile int cvi = 1;
135
  const int& r2 = cvi; // error: type qualifiers dropped
136
  double d2 = 1.0;
 
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]]),
 
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
 
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;