Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct cast to be used on enums?

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?

like image 721
snoopy Avatar asked Dec 09 '25 15:12

snoopy


2 Answers

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.

like image 199
Alex Avatar answered Dec 12 '25 05:12

Alex


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);

like image 25
bames53 Avatar answered Dec 12 '25 04:12

bames53



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!