From Jason Turner

[expr.static.cast]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp6dekenu2/{from.md → to.md} +34 -60
tmp/tmp6dekenu2/{from.md → to.md} RENAMED
@@ -2,15 +2,14 @@
2
 
3
  The result of the expression `static_cast<T>(v)` is the result of
4
  converting the expression `v` to type `T`. If `T` is an lvalue reference
5
  type or an rvalue reference to function type, the result is an lvalue;
6
  if `T` is an rvalue reference to object type, the result is an xvalue;
7
- otherwise, the result is a prvalue. The `static_cast` operator shall not
8
- cast away constness [[expr.const.cast]].
9
 
10
  An lvalue of type “*cv1* `B`”, where `B` is a class type, can be cast to
11
- type “reference to *cv2* `D`”, where `D` is a class derived
12
  [[class.derived]] from `B`, if *cv2* is the same cv-qualification as, or
13
  greater cv-qualification than, *cv1*. If `B` is a virtual base class of
14
  `D` or a base class of a virtual base class of `D`, or if no valid
15
  standard conversion from “pointer to `D`” to “pointer to `B`” exists
16
  [[conv.ptr]], the program is ill-formed. An xvalue of type “*cv1* `B`”
@@ -41,14 +40,25 @@ class subobject thereof; otherwise, the lvalue-to-rvalue conversion
41
  used as the operand of the `static_cast` for the remainder of this
42
  subclause. If `T2` is an inaccessible [[class.access]] or ambiguous
43
  [[class.member.lookup]] base class of `T1`, a program that necessitates
44
  such a cast is ill-formed.
45
 
46
- An expression E can be explicitly converted to a type `T` if there is an
47
- implicit conversion sequence [[over.best.ics]] from E to `T`, if
48
- overload resolution for a direct-initialization [[dcl.init]] of an
49
- object or reference of type `T` from E would find at least one viable
 
 
 
 
 
 
 
 
 
 
 
50
  function [[over.match.viable]], or if `T` is an aggregate type
51
  [[dcl.init.aggr]] having a first element `x` and there is an implicit
52
  conversion sequence from E to the type of `x`. If `T` is a reference
53
  type, the effect is the same as performing the declaration and
54
  initialization
@@ -59,59 +69,23 @@ T t(E);
59
 
60
  for some invented temporary variable `t` [[dcl.init]] and then using the
61
  temporary variable as the result of the conversion. Otherwise, the
62
  result object is direct-initialized from E.
63
 
64
- [*Note 1*: The conversion is ill-formed when attempting to convert an
65
  expression of class type to an inaccessible or ambiguous base
66
  class. — *end note*]
67
 
68
- [*Note 2*: If `T` is “array of unknown bound of `U`”, this
69
  direct-initialization defines the type of the expression as
70
  `U[1]`. — *end note*]
71
 
72
- Otherwise, the `static_cast` shall perform one of the conversions listed
73
- below. No other conversion shall be performed explicitly using a
74
- `static_cast`.
75
-
76
- Any expression can be explicitly converted to type cv `void`, in which
77
- case the operand is a discarded-value expression [[expr.prop]].
78
-
79
- [*Note 3*: Such a `static_cast` has no result as it is a prvalue of
80
- type `void`; see  [[basic.lval]]. — *end note*]
81
-
82
- [*Note 4*: However, if the value is in a temporary object
83
- [[class.temporary]], the destructor for that object is not executed
84
- until the usual time, and the value of the object is preserved for the
85
- purpose of executing the destructor. — *end note*]
86
-
87
- The inverse of any standard conversion sequence [[conv]] not containing
88
- an lvalue-to-rvalue [[conv.lval]], array-to-pointer [[conv.array]],
89
- function-to-pointer [[conv.func]], null pointer [[conv.ptr]], null
90
- member pointer [[conv.mem]], boolean [[conv.bool]], or function pointer
91
- [[conv.fctptr]] conversion, can be performed explicitly using
92
- `static_cast`. A program is ill-formed if it uses `static_cast` to
93
- perform the inverse of an ill-formed standard conversion sequence.
94
-
95
- [*Example 2*:
96
-
97
- ``` cpp
98
- struct B { };
99
- struct D : private B { };
100
- void f() {
101
- static_cast<D*>((B*)0); // error: B is a private base of D
102
- static_cast<int B::*>((int D::*)0); // error: B is a private base of D
103
- }
104
- ```
105
-
106
- — *end example*]
107
-
108
- The lvalue-to-rvalue [[conv.lval]], array-to-pointer [[conv.array]], and
109
- function-to-pointer [[conv.func]] conversions are applied to the
110
- operand. Such a `static_cast` is subject to the restriction that the
111
- explicit conversion does not cast away constness [[expr.const.cast]],
112
- and the following additional rules for specific cases:
113
 
114
  A value of a scoped enumeration type [[dcl.enum]] can be explicitly
115
  converted to an integral type; the result is the same as that of
116
  converting to the enumeration’s underlying type and then to the
117
  destination type. A value of a scoped enumeration type can also be
@@ -164,14 +138,13 @@ pointer-to-member-function types) are never cv-qualified
164
 
165
  If no valid standard conversion from “pointer to member of `B` of type
166
  `T`” to “pointer to member of `D` of type `T`” exists [[conv.mem]], the
167
  program is ill-formed. The null member pointer value [[conv.mem]] is
168
  converted to the null member pointer value of the destination type. If
169
- class `B` contains the original member, or is a base or derived class of
170
- the class containing the original member, the resulting pointer to
171
- member points to the original member. Otherwise, the behavior is
172
- undefined.
173
 
174
  [*Note 6*: Although class `B` need not contain the original member, the
175
  dynamic type of the object with which indirection through the pointer to
176
  member is performed must contain the original member; see 
177
  [[expr.mptr.oper]]. — *end note*]
@@ -179,17 +152,18 @@ member is performed must contain the original member; see 
179
  A prvalue of type “pointer to *cv1* `void`” can be converted to a
180
  prvalue of type “pointer to *cv2* `T`”, where `T` is an object type and
181
  *cv2* is the same cv-qualification as, or greater cv-qualification than,
182
  *cv1*. If the original pointer value represents the address `A` of a
183
  byte in memory and `A` does not satisfy the alignment requirement of
184
- `T`, then the resulting pointer value is unspecified. Otherwise, if the
185
- original pointer value points to an object *a*, and there is an object
186
- *b* of type similar to `T` that is pointer-interconvertible
187
- [[basic.compound]] with *a*, the result is a pointer to *b*. Otherwise,
188
- the pointer value is unchanged by the conversion.
 
189
 
190
- [*Example 3*:
191
 
192
  ``` cpp
193
  T* p1 = new T;
194
  const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
195
  bool b = p1 == p2; // b will have the value true.
 
2
 
3
  The result of the expression `static_cast<T>(v)` is the result of
4
  converting the expression `v` to type `T`. If `T` is an lvalue reference
5
  type or an rvalue reference to function type, the result is an lvalue;
6
  if `T` is an rvalue reference to object type, the result is an xvalue;
7
+ otherwise, the result is a prvalue.
 
8
 
9
  An lvalue of type “*cv1* `B`”, where `B` is a class type, can be cast to
10
+ type “reference to *cv2* `D`”, where `D` is a complete class derived
11
  [[class.derived]] from `B`, if *cv2* is the same cv-qualification as, or
12
  greater cv-qualification than, *cv1*. If `B` is a virtual base class of
13
  `D` or a base class of a virtual base class of `D`, or if no valid
14
  standard conversion from “pointer to `D`” to “pointer to `B`” exists
15
  [[conv.ptr]], the program is ill-formed. An xvalue of type “*cv1* `B`”
 
40
  used as the operand of the `static_cast` for the remainder of this
41
  subclause. If `T2` is an inaccessible [[class.access]] or ambiguous
42
  [[class.member.lookup]] base class of `T1`, a program that necessitates
43
  such a cast is ill-formed.
44
 
45
+ Any expression can be explicitly converted to type cv `void`, in which
46
+ case the operand is a discarded-value expression [[expr.prop]].
47
+
48
+ [*Note 1*: Such a `static_cast` has no result as it is a prvalue of
49
+ type `void`; see  [[basic.lval]]. — *end note*]
50
+
51
+ [*Note 2*: However, if the value is in a temporary object
52
+ [[class.temporary]], the destructor for that object is not executed
53
+ until the usual time, and the value of the object is preserved for the
54
+ purpose of executing the destructor. — *end note*]
55
+
56
+ Otherwise, an expression E can be explicitly converted to a type `T` if
57
+ there is an implicit conversion sequence [[over.best.ics]] from E to
58
+ `T`, if overload resolution for a direct-initialization [[dcl.init]] of
59
+ an object or reference of type `T` from E would find at least one viable
60
  function [[over.match.viable]], or if `T` is an aggregate type
61
  [[dcl.init.aggr]] having a first element `x` and there is an implicit
62
  conversion sequence from E to the type of `x`. If `T` is a reference
63
  type, the effect is the same as performing the declaration and
64
  initialization
 
69
 
70
  for some invented temporary variable `t` [[dcl.init]] and then using the
71
  temporary variable as the result of the conversion. Otherwise, the
72
  result object is direct-initialized from E.
73
 
74
+ [*Note 3*: The conversion is ill-formed when attempting to convert an
75
  expression of class type to an inaccessible or ambiguous base
76
  class. — *end note*]
77
 
78
+ [*Note 4*: If `T` is “array of unknown bound of `U`”, this
79
  direct-initialization defines the type of the expression as
80
  `U[1]`. — *end note*]
81
 
82
+ Otherwise, the lvalue-to-rvalue [[conv.lval]], array-to-pointer
83
+ [[conv.array]], and function-to-pointer [[conv.func]] conversions are
84
+ applied to the operand, and the conversions that can be performed using
85
+ `static_cast` are listed below. No other conversion can be performed
86
+ using `static_cast`.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
  A value of a scoped enumeration type [[dcl.enum]] can be explicitly
89
  converted to an integral type; the result is the same as that of
90
  converting to the enumeration’s underlying type and then to the
91
  destination type. A value of a scoped enumeration type can also be
 
138
 
139
  If no valid standard conversion from “pointer to member of `B` of type
140
  `T`” to “pointer to member of `D` of type `T`” exists [[conv.mem]], the
141
  program is ill-formed. The null member pointer value [[conv.mem]] is
142
  converted to the null member pointer value of the destination type. If
143
+ class `B` contains the original member, or is a base class of the class
144
+ containing the original member, the resulting pointer to member points
145
+ to the original member. Otherwise, the behavior is undefined.
 
146
 
147
  [*Note 6*: Although class `B` need not contain the original member, the
148
  dynamic type of the object with which indirection through the pointer to
149
  member is performed must contain the original member; see 
150
  [[expr.mptr.oper]]. — *end note*]
 
152
  A prvalue of type “pointer to *cv1* `void`” can be converted to a
153
  prvalue of type “pointer to *cv2* `T`”, where `T` is an object type and
154
  *cv2* is the same cv-qualification as, or greater cv-qualification than,
155
  *cv1*. If the original pointer value represents the address `A` of a
156
  byte in memory and `A` does not satisfy the alignment requirement of
157
+ `T`, then the resulting pointer value [[basic.compound]] is unspecified.
158
+ Otherwise, if the original pointer value points to an object *a*, and
159
+ there is an object *b* of type similar to `T` that is
160
+ pointer-interconvertible [[basic.compound]] with *a*, the result is a
161
+ pointer to *b*. Otherwise, the pointer value is unchanged by the
162
+ conversion.
163
 
164
+ [*Example 2*:
165
 
166
  ``` cpp
167
  T* p1 = new T;
168
  const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
169
  bool b = p1 == p2; // b will have the value true.