'bitwise operations with c++11 enums

I have this c++11 class which contains a variety of enums. These enums contain bitmasks which eventual all get combined together into an 8-bit values using bitwise operators.

It looks like this:

class SX1509
{
public:

  enum class DriverMode
  {
    LINEAR = 0b00000000,
    LOGARITHMIC = 0b10000000
  };

  enum class ClockSpeed
  {
    ULTRA_FAST = 0b00010000,
    EXTRA_FAST = 0b00100000,
    FAST = 0b00110000,
    MEDIUM = 0b01000000,
    SLOW = 0b01010000,
    EXTRA_SLOW = 0b01100000,
    ULTRA_SLOW = 0b01110000,
  };

  SX1509()
  {
    this->config(DriverMode::LOGARITHMIC, ClockSpeed::EXTRA_FAST)
  };

  void config(DriverMode driverMode, ClockSpeed clockSpeed) {
    uint8_t config = driverMode | clockSpeed;
    i2c->write(config);
  }

}

However, after changing all my enum definitions to enum class the compiler spit out this error which I do not understand 👇

error: no match for 'operator|' (operand types are 'SX1509::DriverMode' and 'SX1509::ClockSpeed')

What is going on here?



Solution 1:[1]

enum class enumerations do not get implicitly converted to integers, unlike regular enumerations.

I would do at least two things. First, explicitly indicate the underlying type of the enum class, e.g.:

  enum class: uint8_t DriverMode
  {
    LINEAR = 0b00000000,
    LOGARITHMIC = 0b10000000
  };

While this won't help with explicit conversion, it will help with wonkiness due to conversion from signed to unsigned.

Second, explicitly convert the enumeration values, e.g.,

uint8_t config = static_cast<uint8_t>(driverMode) | static_cast<uint8_t>(clockSpeed);

You may want to use a typedef alias for uint8_t, e.g.,

typedef uint8_t MyEnumUnderlyingType;

instead of using the raw uint8_t.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jjramsey