If I remember right a C-Style conversion is nothing more than an ordered set of conversions static_cast, dynamic_cast, reinterpret_cast, static_cast...,
consider:
enum NUMBERS
{
NUMBER_ONE,
NUMBER_TWO
};
void Do( NUMBERS a )
{
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int a = 1;
Do( a ); //C2664
return 0;
}
a C-Style conversion would do
Do( (NUMBERS)a );
What I would like to know is, what is the correct non C-Style conversion to be made, why?
The correct way would be:
static_cast<NUMBERS>(a)
Because:
8) Integer, floating-point, or enumeration type can be converted to any enumeration type (the result is unspecified if the value of expression, converted to the enumeration's underlying type, is not one of the target enumeration values)
Source: http://en.cppreference.com/w/cpp/language/static_cast
dynamic_cast does runtime checks using RTTI, so it only applies to classes with at least one virtual method.
reinterprest_cast is designed to tell the compiler to treat a specific piece of memory as some different type, without any actual runtime conversions.
static_cast<NUMBERS>(a)
Because the specification for static_cast includes this:
A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resulting value is unspecified (and might not be in that range). A value of floating-point type can also be converted to an enumeration type. The resulting value is the same as converting the original value to the underlying type of the enumeration (4.9), and subsequently to the enumeration type.
static_cast is for generally taking values of one type and getting that value represented as another type. There are about two pages of specification covering all the details, but if you understand that basic idea, then you'll probably know when you want to use static_cast. E.g., if you want to convert an integral value from one integral type to another or if you want to convert a floating point value to an integral value.
dynamic_cast is for working with dynamic types, which is mostly only useful for polymorphic, user-defined types. E.g., convert Base * to Derived * iff the referenced object actually is a Derived.
reinterpret_cast is typically for taking the representation of a value in one type, and getting the value that has the same representation in another type; i.e., type punning (even though a lot of type punning is actually not legal in C++). E.g., if you want to access an integer's storage as an array of char.
const_cast is for adding and removing cv qualifiers (const and volatile) at any level of a type. E.g., int const * volatile **i; const_cast<int volatile ** const *>(i);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With