Why does is_convertible<EnumClass, int> return false?

95 views Asked by At

I don't understand why std::is_convertible_v<EnumClass, int> returns false in this example, especially given that static_cast<int>(enumClassValue) works correctly.

#include <iostream>

enum Enum {X = 5};
enum class EnumClass {X = 5};

int main() {
    Enum enumValue = Enum::X;
    std::cout << static_cast<int>(enumValue) << std::endl;
    std::cout << std::is_convertible_v<Enum, int> << std::endl;

    EnumClass enumClassValue = EnumClass::X;
    std::cout << static_cast<int>(enumClassValue) << std::endl;
    std::cout << std::is_convertible_v<EnumClass, int> << std::endl;

    return 0;
}
2

There are 2 answers

0
Matteo Italia On BEST ANSWER

std::is_convertible_v<From, To> returns true if a value of type From is implicitly convertible to type To.

https://en.cppreference.com/w/cpp/types/is_convertible

If the imaginary function definition To test() { return std::declval<From>(); } is well-formed, (that is, either std::declval<From>() can be converted to To using implicit conversions, or both From and To are possibly cv-qualified void), provides the member constant value equal to true. Otherwise value is false.

Values of enum class types (unlike regular enums) require an explicit conversion to perform that conversion; hence, the valued returned by is_convertible_v is correct.

0
user12002570 On

In the latter case you have a scoped enum, which isn't implicitly convertible to an integer. This can be seen from enum declaration:

There are no implicit conversions from the values of a scoped enumerator to integral types, although static_cast may be used to obtain the numeric value of the enumerator.


On the other hand, an unscoped enum does allow implicit conversion, so the observed behavior.

From implicit conversion:

A prvalue of an unscoped enumeration type whose underlying type is not fixed can be converted to a prvalue of the first type from the following list able to hold their entire value range:

  • int
  • ...