Search code examples
c++c++11enumsoperator-overloadingbitwise-operators

How to overload |= operator on scoped enum?


How can I overload the |= operator on a strongly typed (scoped) enum (in C++11, GCC)?

I want to test, set and clear bits on strongly typed enums. Why strongly typed? Because my books say it is good practice. But this means I have to static_cast<int> everywhere. To prevent this, I overload the | and & operators, but I can't figure out how to overload the |= operator on an enum. For a class you'd simply put the operator definition in the class, but for enums that doesn't seem to work syntactically.

This is what I have so far:

enum class NumericType
{
    None                    = 0,

    PadWithZero             = 0x01,
    NegativeSign            = 0x02,
    PositiveSign            = 0x04,
    SpacePrefix             = 0x08
};

inline NumericType operator |(NumericType a, NumericType b)
{
    return static_cast<NumericType>(static_cast<int>(a) | static_cast<int>(b));
}

inline NumericType operator &(NumericType a, NumericType b)
{
    return static_cast<NumericType>(static_cast<int>(a) & static_cast<int>(b));
}

The reason I do this: this is the way it works in strongly-typed C#: an enum there is just a struct with a field of its underlying type, and a bunch of constants defined on it. But it can have any integer value that fits in the enum's hidden field.

And it seems that C++ enums work in the exact same way. In both languages casts are required to go from enum to int or vice versa. However, in C# the bitwise operators are overloaded by default, and in C++ they aren't.


Solution

  • inline NumericType& operator |=(NumericType& a, NumericType b)
    {
        return a= a |b;
    }
    

    This works? Compile and run: (Ideone)

    #include <iostream>
    using namespace std;
    
    enum class NumericType
    {
        None                    = 0,
    
        PadWithZero             = 0x01,
        NegativeSign            = 0x02,
        PositiveSign            = 0x04,
        SpacePrefix             = 0x08
    };
    
    inline NumericType operator |(NumericType a, NumericType b)
    {
        return static_cast<NumericType>(static_cast<int>(a) | static_cast<int>(b));
    }
    
    inline NumericType operator &(NumericType a, NumericType b)
    {
        return static_cast<NumericType>(static_cast<int>(a) & static_cast<int>(b));
    }
    
    inline NumericType& operator |=(NumericType& a, NumericType b)
    {
        return a= a |b;
    }
    
    int main() {
        // your code goes here
        NumericType a=NumericType::PadWithZero;
        a|=NumericType::NegativeSign;
        cout << static_cast<int>(a) ;
        return 0;
    }
    

    print 3.