Which operators are automatically defined for scoped enumerations?

Viewed 81

For unscoped enumerations, the answer is "most of them" because of the implicit conversions to the underlying integral type. However, scoped enumerations do not have this implicit conversion. Instead, some but not all of the operators available for unscoped enumerations are defined for them.

#include <iostream>

enum class Color{
    Red,
    Green,
    Blue
};

int main()
{
    std::cout << (Color::Red < Color::Green) << '\n';
    // Fine, operator< is defined for Color
    std::cout << (Color::Red + Color::Green == Color::Green) << '\n';
    // no match for 'operator+'
}

My guess would be that the relational operators are defined but the arithmetic ones aren't, but I don't see anything explicitly saying so on the cppreference page and have not done the actual standard diving to know what C++ proper has to say about the matter.

1 Answers

The relational operators are opted in via [expr.rel]

The usual arithmetic conversions are performed on operands of arithmetic or enumeration type. If both operands are pointers, pointer conversions and qualification conversions are performed to bring them to their composite pointer type. After conversions, the operands shall have the same type.

The arithmetic operators are opted-out by ommision. For example: [expr.add]

the left operand is a pointer to a completely-defined object type and the right operand has integral or unscoped enumeration type.

Related