What are the proper uses of:
static_castdynamic_castconst_castreinterpret_cast(type)value(C-style cast)type(value)(function-style cast)
How does one decide which to use in which specific cases?
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
static_caststatic_castis the first cast you should attempt to use. It does things like implicit conversions between types (such asinttofloat, or pointer tovoid*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly statingstatic_castisn’t necessary, but it’s important to note that theT(something)syntax is equivalent to(T)somethingand should be avoided (more on that later). AT(something, something_else)is safe, however, and guaranteed to call the constructor.static_castcan also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn’t cast throughvirtualinheritance. It does not do checking, however, and it is undefined behavior tostatic_castdown a hierarchy to a type that isn’t actually the type of the object.const_castconst_castcan be used to remove or addconstto a variable; no other C++ cast is capable of removing it (not evenreinterpret_cast). It is important to note that modifying a formerlyconstvalue is only undefined if the original variable isconst; if you use it to take theconstoff a reference to something that wasn’t declared withconst, it is safe. This can be useful when overloading member functions based onconst, for instance. It can also be used to addconstto an object, such as to call a member function overload.const_castalso works similarly onvolatile, though that’s less common.dynamic_castdynamic_castis exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You can use it for more than just casting downwards – you can cast sideways or even up another chain. Thedynamic_castwill seek out the desired object and return it if possible. If it can’t, it will returnnullptrin the case of a pointer, or throwstd::bad_castin the case of a reference.dynamic_casthas some limitations, though. It doesn’t work if there are multiple objects of the same type in the inheritance hierarchy (the so-called ‘dreaded diamond’) and you aren’t usingvirtualinheritance. It also can only go through public inheritance – it will always fail to travel throughprotectedorprivateinheritance. This is rarely an issue, however, as such forms of inheritance are rare.reinterpret_castreinterpret_castis the most dangerous cast, and should be used very sparingly. It turns one type directly into another — such as casting the value from one pointer to another, or storing a pointer in anint, or all sorts of other nasty things. Largely, the only guarantee you get withreinterpret_castis that normally if you cast the result back to the original type, you will get the exact same value (but not if the intermediate type is smaller than the original type). There are a number of conversions thatreinterpret_castcannot do, too. It’s often abused for particularly weird conversions and bit manipulations, like turning a raw data stream into actual data, or storing data in the low bits of a pointer to aligned data. For those cases, seestd::bit_cast.C-Style Cast and Function-Style Cast
C-style cast and function-style cast are casts using
(type)objectortype(object), respectively, and are functionally equivalent. They are defined as the first of the following which succeeds:const_caststatic_cast(though ignoring access restrictions)static_cast(see above), thenconst_castreinterpret_castreinterpret_cast, thenconst_castIt can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a
reinterpret_cast, and the latter should be preferred when explicit casting is needed, unless you are surestatic_castwill succeed orreinterpret_castwill fail. Even then, consider the longer, more explicit option.C-style casts also ignore access control when performing a
static_cast, which means that they have the ability to perform an operation that no other cast can. This is mostly a kludge, though, and in my mind is just another reason to avoid C-style casts.std::bit_cast[C++20]std::bit_castcopies the bits and bytes of the source object (its representation) directly into a new object of the target type. It’s a standards-compliant way to do type punning. If you find yourself writing*reinterpret_cast<SomeType*>(&x), you probably should usestd::bit_cast<SomeType>(x)instead.std::bit_castis declared in<bit>. The objects must be the same size and be trivially copyable. If you can’t yet use C++20, usememcpyto copy the source value into a variable of the desired type.