Reputation: 34527
#include <iostream>
enum mode { MODE0=0, MODE1, NUM_MODES};
int main(int args, char ** argv) {
int i = 1;
std::cout << (i == MODE0 ? "true" : "false") << "\n";
std::cout << (i == MODE1 ? "true" : "false") << "\n";
mode test;
test = i; // error
}
Why is it that the comparison of i to enum values works fine, but I get compilation error when assigning mode test variable to an integer value?
enum.cc:10:8: error: invalid conversion from 'int' to 'mode' [-fpermissive]
My question is specifically about why comparison works and assignment doesn't (not how to fix my code) and it has received a couple of good explanations below.
Upvotes: 3
Views: 3114
Reputation: 29023
MODE0
, MODE1
and NUM_MODES
are guaranteed to be convertible to int
(the underlying type of the enum
) but the reverse is not true. Not all int
can be converted to mode
. For example, what is the matching mode
for the int
42? Simply put, only the implicit conversion from enum
to int
is defined, the opposite implicit conversion is not defined.
If you want to convert from int
to mode
you can preform a static_cast
to signal that you are taking the responsibility for the value being converted. Try
test = static_cast<mode>(i);
You can use strongly typed enumerations by adding the class
keyword to your enum
to prevent any implicit casts and to limit the scope of the enum
value names. The definition would look like enum class mode { MODE0 = 0, MODE1, NUM_MODES };
. In this case, you must quality the enum
value names, for example, you would need to use mode::MODE0
instead of MODE0
. This has the advantage that it avoids name collisions.
Upvotes: 10
Reputation: 180490
Look at it this way. When you do a comparison it doesn't matter if the int
is not a valid possible value. If it is not then the comparison will fail and we can go on. Now when we go and try to assign an int
to an enum
you could assign to it a value that isn't mapped to the enum values. Since we don't want this implicitly happening the conversion is invalid. If you want to tell the compiler that it is okay, you know what you are doing, then you can cast it like:
test = static_cast<mode>(i);
Upvotes: 1
Reputation: 76245
It's because there is a conversion from an enumerated type to int
but there is no conversion in the opposite direction. For the comparison, MODE0
gets promoted to int
. For the assignment, i
would have to be converted to mode
.
Upvotes: 1