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.
|
| 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 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 65 |
expression of class type to an inaccessible or ambiguous base
|
| 66 |
class. — *end note*]
|
| 67 |
|
| 68 |
-
[*Note
|
| 69 |
direct-initialization defines the type of the expression as
|
| 70 |
`U[1]`. — *end note*]
|
| 71 |
|
| 72 |
-
Otherwise, the
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 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
|
| 170 |
-
|
| 171 |
-
|
| 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.
|
| 185 |
-
original pointer value points to an object *a*, and
|
| 186 |
-
*b* of type similar to `T` that is
|
| 187 |
-
[[basic.compound]] with *a*, the result is a
|
| 188 |
-
the pointer value is unchanged by the
|
|
|
|
| 189 |
|
| 190 |
-
[*Example
|
| 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.
|