ivaigult ivaigult - 3 months ago 15
C++ Question

Why implicit conversion from strongly typed enum to its underlying type is not allowed?

Let's consider the following code:

#include <type_traits>

enum class foo_bar : unsigned
{
foo,
bar,
};

int main()
{
foo_bar bar = foo_bar::bar;
// unsigned a = bar; -- error: cannot convert ‘foo_bar’ to ‘unsigned int’ in initialization
unsigned a = static_cast<std::underlying_type<foo_bar>::type>(bar);
return 0;
}


Why the implicit conversion is not allowed? The underlying type is known, type of
a
matches the
foo_bar
underlying type. The implicit conversion seems to be safe and could be performed without losing an information. Why the cast is necessary from the language design perspective?

Answer

From N2347, the problem with implicit integral promotion is that you can compare two different enums:

enum Color { ClrRed, ClrOrange, ClrYellow, ClrGreen, ClrBlue, ClrViolet };
enum Alert { CndGreen, CndYellow, CndRed };
Color c = ClrGreen;
Alert a = CndGreen;
bool armWeapons = ( a >= c ); // compiles but does not make sense

To see what is really going here, you can emulate enum classes with structures:

struct A {
    operator int() const {
        // for simplicity, just return fixed value
        return 1;
    }
};

struct B {
    operator int() const {
        return 2;
    }
};

A a;
B b;
int i = b; // ok
bool x = (a < b); // yay, this compiles

Now, the correct solution would be to make the operators explicit:

struct B {
    explicit operator int() const {
        return 2;
    }
};

A a;
B b;
bool x = (a < b); // finally does not work
int i = b; // but now this does not work without explicit cast either