c++enumsunderlyingtype

No suitable constructor to convert from enum to underlying type


I have an enum class as defined here

// namespace Types
enum class MessageType : uint32_t
{
  COMPUTE_SUM_MESSAGE = 1
};

I want a function that can take an enum value and convert it to a byte array. I tried to use underlying_type to convert my enum value from a MessageType to an uint32_t but I get a no suitable constructor exists to convert it.

void ConvertMessageTypeToByteArray(Types::MessageType message_type)
{
  using MessageTypeUnderlying = std::underlying_type<Types::MessageType>;
  // Can not static cast the message_type to MessageTypeUnderlying 
  MessageTypeUnderlying data = static_cast<MessageTypeUnderlying>(message_type);
}

Is it possible to do something similar to this? I would like to have message_type as an unsigned 32 bit integer, which is its underlying type.


Solution

  • Your using statement is wrong. It is defining MessageTypeUnderlying as an alias for the std::underlying_type struct itself, not the enum's actual underlying type that it represents. Thus, you get the error when you try to cast an enum value to the struct type. The compiler's full error message should be pointing this out to you.

    To fix this, you need to instead define MessageTypeUnderlying as an alias for the type that is specified by the std::underlying_type::type field:

    Member types

    Name Definition
    type the underlying type of T
    using MessageTypeUnderlying = std::underlying_type<Types::MessageType>::type;
    

    Alternatively, in C++14 and later, you can use the helper std::underlying_type_t alias instead:

    Helper types

    template< class T >
    using underlying_type_t = typename underlying_type<T>::type;
    
    using MessageTypeUnderlying = std::underlying_type_t<Types::MessageType>;
    

    That being said, C++23 adds std::to_underlying(), which does exactly what you are trying to do manually:

    Converts an enumeration to its underlying type. Equivalent to return static_cast<std::underlying_type_t<Enum>>(e);.

    auto data = std::to_underlying(message_type);