Стандарт C++ 11 (1119564), страница 35
Текст из файла (страница 35)
[ Example:class D { /* ...D d1;const D d2;typeid(d1)typeid(D)typeid(D)typeid(D)========*/ };typeid(d2);typeid(const D);typeid(d2);typeid(const D&);////////yieldsyieldsyieldsyieldstruetruetruetrue— end example ]6If the header <typeinfo> (18.7.1) is not included prior to a use of typeid, the program is ill-formed.7[ Note: 12.7 describes the behavior of typeid applied to an object under construction or destruction. — endnote ]5.2.9Static cast[expr.static.cast]1The result of the expression static_cast<T>(v) is the result of converting the expression v to type T.
If Tis an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is an rvaluereference to object type, the result is an xvalue; otherwise, the result is a prvalue. The static_cast operatorshall not cast away constness (5.2.11).2An lvalue of type “cv1 B,” where B is a class type, can be cast to type “reference to cv2 D,” where D is a classderived (Clause 10) from B, if a valid standard conversion from “pointer to D” to “pointer to B” exists (4.10),cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and B is neither a virtual base classof D nor a base class of a virtual base class of D.
The result has type “cv2 D.” An xvalue of type “cv1 B” maybe cast to type “rvalue reference to cv2 D” with the same constraints as for an lvalue of type “cv1 B.” If theobject of type “cv1 B” is actually a subobject of an object of type D, the result refers to the enclosing objectof type D. Otherwise, the result of the cast is undefined. [ Example:struct B { };struct D : public B { };D d;B &br = d;static_cast<D&>(br);// produces lvalue to the original d object68) If p is an expression of pointer type, then *p, (*p), *(p), ((*p)), *((p)), and so on all meet this requirement.§ 5.2.9104© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)— end example ]3A glvalue of type “cv1 T1” can be cast to type “rvalue reference to cv2 T2” if “cv2 T2” is reference-compatiblewith “cv1 T1” (8.5.3).
The result refers to the object or the specified base class subobject thereof. If T2 isan inaccessible (Clause 11) or ambiguous (10.2) base class of T1, a program that necessitates such a cast isill-formed.4Otherwise, an expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration T t(e); is well-formed, for some invented temporary variable t (8.5).
Theeffect of such an explicit conversion is the same as performing the declaration and initialization and thenusing the temporary variable as the result of the conversion. The expression e is used as a glvalue if andonly if the initialization uses it as a glvalue.5Otherwise, the static_cast shall perform one of the conversions listed below. No other conversion shall beperformed explicitly using a static_cast.6Any expression can be explicitly converted to type cv void, in which case it becomes a discarded-valueexpression (Clause 5). [ Note: however, if the value is in a temporary object (12.2), the destructor for thatobject is not executed until the usual time, and the value of the object is preserved for the purpose ofexecuting the destructor.
— end note ]7The inverse of any standard conversion sequence (Clause 4) not containing an lvalue-to-rvalue (4.1), arrayto-pointer (4.2), function-to-pointer (4.3), null pointer (4.10), null member pointer (4.11), or boolean (4.12)conversion, can be performed explicitly using static_cast. A program is ill-formed if it uses static_castto perform the inverse of an ill-formed standard conversion sequence. [ Example:struct B { };struct D : private B { };void f() {static_cast<D*>((B*)0);static_cast<int B::*>((int D::*)0);}// Error: B is a private base of D.// Error: B is a private base of D.— end example ]8The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) conversions are applied tothe operand.
Such a static_cast is subject to the restriction that the explicit conversion does not castaway constness (5.2.11), and the following additional rules for specific cases:9A value of a scoped enumeration type (7.2) can be explicitly converted to an integral type. The value isunchanged if the original value can be represented by the specified type. Otherwise, the resulting value isunspecified.
A value of a scoped enumeration type can also be explicitly converted to a floating-point type;the result is the same as that of converting from the original value to the floating-point type.10A value of integral or enumeration type can be explicitly converted to an enumeration type. The value isunchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resultingvalue is unspecified (and might not be in that range).
A value of floating-point type can also be convertedto an enumeration type. The resulting value is the same as converting the original value to the underlyingtype of the enumeration (4.9), and subsequently to the enumeration type.11A prvalue of type “pointer to cv1 B,” where B is a class type, can be converted to a prvalue of type “pointerto cv2 D,” where D is a class derived (Clause 10) from B, if a valid standard conversion from “pointer to D” to“pointer to B” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, and Bis neither a virtual base class of D nor a base class of a virtual base class of D. The null pointer value (4.10)is converted to the null pointer value of the destination type.
If the prvalue of type “pointer to cv1 B” points§ 5.2.9© ISO/IEC 2011 – All rights reserved105ISO/IEC 14882:2011(E)to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing objectof type D. Otherwise, the result of the cast is undefined.12A prvalue of type “pointer to member of D of type cv1 T” can be converted to a prvalue of type “pointer tomember of B” of type cv2 T, where B is a base class (Clause 10) of D, if a valid standard conversion from“pointer to member of B of type T” to “pointer to member of D of type T” exists (4.11), and cv2 is the samecv-qualification as, or greater cv-qualification than, cv1.69 The null member pointer value (4.11) is convertedto the null member pointer value of the destination type.
If class B contains the original member, or is a baseor derived class of the class containing the original member, the resulting pointer to member points to theoriginal member. Otherwise, the result of the cast is undefined. [ Note: although class B need not containthe original member, the dynamic type of the object on which the pointer to member is dereferenced mustcontain the original member; see 5.5. — end note ]13A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T,” whereT is an object type and cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. The nullpointer value is converted to the null pointer value of the destination type. A value of type pointer to objectconverted to “pointer to cv void” and back, possibly with different cv-qualification, shall have its originalvalue.
[ Example:T* p1 = new T;const T* p2 = static_cast<const T*>(static_cast<void*>(p1));bool b = p1 == p2; // b will have the value true.— end example ]5.2.10Reinterpret cast[expr.reinterpret.cast]1The result of the expression reinterpret_cast<T>(v) is the result of converting the expression v to typeT. If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is anrvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue and the lvalue-torvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are performed on theexpression v.
Conversions that can be performed explicitly using reinterpret_cast are listed below. Noother conversion can be performed explicitly using reinterpret_cast.2The reinterpret_cast operator shall not cast away constness (5.2.11). An expression of integral, enumeration, pointer, or pointer-to-member type can be explicitly converted to its own type; such a cast yields thevalue of its operand.3[ Note: The mapping performed by reinterpret_cast might, or might not, produce a representation different from the original value. — end note ]4A pointer can be explicitly converted to any integral type large enough to hold it.
The mapping function isimplementation-defined. [ Note: It is intended to be unsurprising to those who know the addressing structureof the underlying machine. — end note ] A value of type std::nullptr_t can be converted to an integraltype; the conversion has the same meaning and validity as a conversion of (void*)0 to the integral type.[ Note: A reinterpret_cast cannot be used to convert a value of any type to the type std::nullptr_t.— end note ]5A value of integral type or enumeration type can be explicitly converted to a pointer.
A pointer convertedto an integer of sufficient size (if any such exists on the implementation) and back to the same pointer typewill have its original value; mappings between pointers and integers are otherwise implementation-defined.[ Note: Except as described in 3.7.4.3, the result of such a conversion will not be a safely-derived pointervalue. — end note ]69) Function types (including those used in pointer to member function types) are never cv-qualified; see 8.3.5.§ 5.2.10106© ISO/IEC 2011 – All rights reservedISO/IEC 14882:2011(E)6A function pointer can be explicitly converted to a function pointer of a different type.