Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      static_cast conversion

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Expressions
      General
      Literals
      Operators
      Conversions
       

      Converts between types using a combination of implicit and user-defined conversions.

      Contents

      [edit]Syntax

      static_cast<target-type >(expression )

      Returns a value of typetarget-type.

      [edit]Explanation

      Only the following conversions can be done withstatic_cast, except when such conversions wouldcast away constness (or volatility).

      1) Ifexpression is an lvalue of type “cv1Base” andtarget-type is “reference tocv2Derived”, the result refers to the object of typeDerived enclosingexpression if all following conditions are satisfied:
      • Derived is a complete class type.
      • Base is a base class ofDerived.
      • cv1 is not a greater cv-qualification thancv2.
      If any of the following conditions is satisfied, the program is ill-formed:
      Ifexpression is actually not a base class subobject of an object of typeDerived, the behavior is undefined.
      struct B{};struct D: B{ B b;}; D d;B& br1= d;B& br2= d.b; static_cast<D&>(br1);// OK, lvalue denoting the original “d” objectstatic_cast<D&>(br2);// UB: the “b” subobject is not a base class subobject
      2) Iftarget-type is “rvalue reference toDerived” andexpression is an xvalue of type “(possibly cv-qualified)Base” such thatBase is a base class ofDerived, the result and constraints of such a conversion are the same as those of the “Base lvalue toDerived reference” conversion.
      3) Iftarget-type is an rvalue reference type and the referenced type isreference-compatible with the type ofexpression,static_cast converts the value ofglvalue, class prvalue, or array prvalue(until C++17)any lvalue(since C++17)expression to xvalue referring to the same object as the expression, or to its base class subobject (depending ontarget-type).[1]
      Iftarget-type is an inaccessible or ambiguous base of the type ofexpression, the program is ill-formed.
      Ifexpression is abit-field lvalue, it is first converted to prvalue of the underlying type.
      (since C++11)
      4) Iftarget-type is the (possibly cv-qualified)void, the conversion has no result. In this case,expression is adiscarded-value expression.
      5) Otherwise,expression can be explicitly converted totarget-type if

      the declarationtarget-typetemp(expression ); is well-formed for some invented temporary variabletemp.

      The effect of such an explicit conversion is the same as performing the declaration and initialization and then usingtemp as the result of the conversion. Theexpression  is used asan lvalue(until C++11)a glvalue(since C++11) if and only if the initialization uses it asan lvalue(until C++11)a glvalue(since C++11).

      (until C++17)

      any of the following conditions is satisfied:

      • There is an implicit conversion sequence fromexpression totarget-type.
      • Theoverload resolution for adirect-initialization of an object or reference of typetarget-type fromexpression would find at least one viable function.
      • target-type is anaggregate type having a first elementx and there is an implicit conversion sequence fromexpression to the type ofx.
      (since C++20)

      The explicit conversion is defined as follows:

      • Iftarget-type is a reference type, the effect is the same as performing the declaration and initializationtarget-typetemp(expression ); for some invented temporary variabletemp and then usingtemp as the result of the conversion.
      • Otherwise, the result object is direct-initialized fromexpression .
      (since C++17)
      6) Otherwise, if the conversion fromexpression totarget-type is an inverse of a standard conversion sequence, and the conversion sequence does not contain any of the following conversions, the conversion can be performed bystatic_cast:
      (since C++17)
      If a program usesstatic_cast to perform the inverse of an ill-formed standard conversion sequence, it is ill-formed.
      7) Otherwise, lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions are applied toexpression. After these conversions, only the following conversions can be performed bystatic_cast:
      a) A value ofscoped enumeration type can be converted to an integer or floating-point type.
      • Iftarget-type is (possibly cv-qualified)bool, the result isfalse if the original value ofexpression is zero andtrue for all other values.
      • Iftarget-type is an integral type other than (possibly cv-qualified)bool, the value is unchanged if the original value ofexpression can be represented bytarget-type. Otherwise, the resulting value is unspecified.
      (until C++20)
      • Iftarget-type is an integral type, the result is the same as that of converting to the enumeration’s underlying type and then totarget-type.
      (since C++20)
      • Iftarget-type is a floating-point type, the result is the same as that of converting from the original value totarget-type.
      (since C++11)
      b) A value of integer or enumeration type can be converted to any complete enumeration type.
      c) A value of a floating-point type can also be converted to any complete enumeration type. The result is the same asconverting the original value ofexpression first to the underlying type oftarget-type, and then totarget-type itself.
      d) A prvalue of floating-point type can be explicitly converted to any other floating-point type.
      • If the source value ofexpression can be represented exactly intarget-type, it does not change.
      • Otherwise, if the source value ofexpression is between two representable values oftarget-type, the result of the conversion is an implementation-defined choice of either of those values.[2]
      • Otherwise, the behavior is undefined.
      (since C++23)
      e)An rvalue(until C++11)A prvalue(since C++11) of type “pointer tocv1Base” can be explicitly converted to the type “pointer tocv2Derived” if all following conditions are satisfied:
      • Derived is a complete class type.
      • Base is a base class ofDerived.
      • cv1 is not a greater cv-qualification thancv2.
      Ifexpression is anull pointer value, the result is a null pointer value of typetarget-type. Otherwise, the result is a pointer to the object of typeDerived enclosing the object of typeBase pointed to byexpression.
      If any of the following conditions is satisfied, the program is ill-formed:
      • Base is avirtual base class ofDerived.
      • Base is a base class of a virtual base class ofDerived.
      • No valid standard conversion from “pointer toDerived” to “pointer toBase” exists.
      Ifexpression is not a null pointer value and does not actually point to a base class subobject of an object of typeDerived, the behavior is undefined.
      f)An rvalue(until C++11)A prvalue(since C++11) of type “pointer to member ofDerived of typecv1T” can be explicitly converted to the type “pointer to member ofBase of typecv2T” if all following conditions are satisfied:
      • Derived is a complete class type.
      • Base is a base class ofDerived.
      • cv1 is not a greater cv-qualification thancv2.
      Ifexpression is a null member pointer value, the result is a null member pointer value of typetarget-type. Otherwise, the result is a pointer to the original (possibly indirect) member of classBase.
      If no valid standard conversion from “pointer to member ofBase of typeT” to “pointer to member ofDerived of typeT” exists, the program is ill-formed.
      Ifexpression is not a null member pointer value and the member it denotes is not a (possibly indirect) member of classBase, the behavior is undefined.
      g)An rvalue(until C++11)A prvalue(since C++11) of type “pointer tocv1void” can be explicitly converted to the type “pointer tocv2T” ifT is an object type andcv1 is not a greater cv-qualification thancv2.
      • Ifexpression is a null pointer value, the result is a null pointer value of typetarget-type.
      • If theexpressionrepresents the addressA of abyte in memory andA satisfies thealignment requirement ofT, then the resulting pointer value also representsA.
      • The result of any other such pointer conversion is unspecified.
      • Ifexpression the result of a prior conversion from an object of type “pointer tocv3T”, the result has the original value.
      (until C++17)
      • Ifexpressionrepresents the addressA of abyte in memory butA does not satisfy thealignment requirement ofT, then the resulting pointer value is unspecified.
      • Otherwise, ifexpression points to an objecta, and there is an objectb of typeT (ignoring cv-qualification) that is pointer-interconvertible (see below) witha, the result is a pointer tob.
      • Otherwise, the pointer value is unchanged by the conversion.
      (since C++17)

      As with all cast expressions, the result is:

      • an lvalue iftarget-type is an lvalue reference type or an rvalue reference to function type(since C++11);
      • an xvalue iftarget-type is an rvalue reference to object type;
      (since C++11)
      • a prvalue otherwise.
      1. This type ofstatic_cast is used to implement move semantics instd::move.
      2. If IEEE arithmetic is supported, rounding defaults to nearest.

      [edit]Pointer-interconvertible objects

      Two objectsa andb arepointer-interconvertible if:

      • they are the same object, or
      • one is a union object and the other is a non-static data member of that object, or
      • one is astandard-layout class object and the other is the first non-static data member of that object or any base class subobject of that object, or
      • there exists an objectc such thata andc are pointer-interconvertible, andc andb are pointer-interconvertible.
      union U{int a;double b;} u;void* x=&u;// x's value is “pointer to u”double* y=static_cast<double*>(x);// y's value is “pointer to u.b”char* z=static_cast<char*>(x);// z's value is “pointer to u”

      [edit]Notes

      Base-to-derived conversions (downcasts) usingstatic_cast make no runtime checks to ensure that thedynamic type of the pointed/referred object isDerived, and may only be used safely if this precondition is guaranteed by other means, such as when implementingstatic polymorphism. Safe downcast may be done withdynamic_cast.

      static_cast may also be used to disambiguate function overloads by performing a function-to-pointer conversion to specific type, as in

      std::for_each(files.begin(), files.end(),static_cast<std::ostream&(*)(std::ostream&)>(std::flush));

      [edit]Keywords

      static_cast

      [edit]Example

      Run this code
      #include <iostream>#include <vector> struct B{int m=42;constchar* hello()const{return"Hello world, this is B!\n";}}; struct D: B{constchar* hello()const{return"Hello world, this is D!\n";}}; enumclass E{ ONE=1, TWO, THREE};enum EU{ ONE=1, TWO, THREE}; int main(){// 1. static downcast    D d;    B& br= d;// upcast via implicit conversionstd::cout<<"1) "<< br.hello();    D& another_d=static_cast<D&>(br);// downcaststd::cout<<"1) "<< another_d.hello(); // 3. lvalue to xvaluestd::vector<int> v0{1,2,3};std::vector<int> v2=static_cast<std::vector<int>&&>(v0);std::cout<<"3) after move, v0.size() = "<< v0.size()<<'\n'; // 4. discarded-value expressionstatic_cast<void>(v2.size()); // 5. initializing conversionint n=static_cast<int>(3.14);std::cout<<"5) n = "<< n<<'\n';std::vector<int> v=static_cast<std::vector<int>>(10);std::cout<<"5) v.size() = "<< v.size()<<'\n'; // 6. inverse of implicit conversionvoid* nv=&n;int* ni=static_cast<int*>(nv);std::cout<<"6) *ni = "<<*ni<<'\n'; // 7a. scoped enum to int    E e= E::TWO;int two=static_cast<int>(e);std::cout<<"7a) "<< two<<'\n'; // 7b. int to enum, enum to another enum    E e2=static_cast<E>(two);[[maybe_unused]]    EU eu=static_cast<EU>(e2); // 7f. pointer to member upcastint D::*pm=&D::m;std::cout<<"7f) "<< br.*static_cast<int B::*>(pm)<<'\n'; // 7g. void* to any object pointervoid* voidp=&e;[[maybe_unused]]std::vector<int>* p=static_cast<std::vector<int>*>(voidp);}

      Output:

      1) Hello world, this is B!1) Hello world, this is D!3) after move, v0.size() = 05) n = 35) v.size() = 106) *ni = 37a) 27f) 42

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 137C++98the constness and volatility of
      pointers tovoid could be casted away
      cv-qualifications cannot be
      casted away in such cases
      CWG 427C++98downcast might be ambiguous with direct-initializationselects downcast in this case
      CWG 439C++98when converting a “pointer to object” to “pointer to
      void” then back to itself, it could only preserve its
      value if the result type has the same cv-qualification
      cv-qualification
      may be different
      CWG 1094C++98the conversion from floating-point values
      to enumeration values was unspecified
      specified
      CWG 1320C++11the conversion from scoped enumeration
      values to bool was unspecified
      specified
      CWG 1412C++98the result of the conversion from
      “pointer to
      void” to “pointer to object” was unclear
      made clear
      CWG 1447C++11the conversion from bit-fields to rvalue references
      was unspecified (cannot bind references to bit-fields)
      specified
      CWG 1766C++98the conversion from integral or enumeration values to enumeration
      values yielded unspecified result ifexpression is out of range
      the behavior is
      undefined in this case
      CWG 1832C++98the conversion from integral or enumeration values to
      enumeration values allowedtarget-type to be incomplete
      not allowed
      CWG 2224C++98the conversion from a member of base class type to
      its complete object of derived class type was valid
      the behavior is
      undefined in this case
      CWG 2254C++11a standard-layout class object with no data members
      was pointer-interconvertible to its first base class
      it is pointer-interconvertible
      to any of its base classes
      CWG 2284C++11a non-standard-layout union object and a non-static data
      member of that object were not pointer-interconvertible
      they are
      CWG 2310C++98for base-to-derived pointer conversions and
      derived-to-base pointer-to-member conversions,
      the derived class type could be incomplete
      must be complete
      CWG 2338C++11the conversion to enumeration types with fixed underlying type
      resulted in undefined behavior ifexpression is out of range
      convert to the underlying type
      first (no undefined behavior)
      CWG 2499C++11a standard-layout class might have a non-pointer-interconvertible
      base class, even though all base subobjects have the same address
      it does not have
      CWG 2718C++98for base-to-derived reference conversions,
      the derived class type could be incomplete
      must be complete
      CWG 2882C++98it was unclear whetherstatic_cast<void>(expr) attempts
      to form an implicit conversion sequence fromexpr tovoid
      no attempt in this case

      [edit]References

      • C++23 standard (ISO/IEC 14882:2024):
      • 7.6.1.9 Static cast [expr.static.cast]
      • C++20 standard (ISO/IEC 14882:2020):
      • 7.6.1.8 Static cast [expr.static.cast]
      • C++17 standard (ISO/IEC 14882:2017):
      • 8.2.9 Static cast [expr.static.cast]
      • C++14 standard (ISO/IEC 14882:2014):
      • 5.2.9 Static cast [expr.static.cast]
      • C++11 standard (ISO/IEC 14882:2011):
      • 5.2.9 Static cast [expr.static.cast]
      • C++98 standard (ISO/IEC 14882:1998):
      • 5.2.9 Static cast [expr.static.cast]
      • C++03 standard (ISO/IEC 14882:2003):
      • 5.2.9 Static cast [expr.static.cast]

      [edit]See also

      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/static_cast&oldid=175308"

      [8]ページ先頭

      ©2009-2025 Movatter.jp