0

Is it possible to define operators tilde ~ for enums? For example I have enum State in my example and I would like to be able to write result &= ~STATE_FAIL;. I did something like this:

#include <iostream>

    enum State
    {
        STATE_OK                     = 0x0,
        STATE_FAIL                   = 0x1,    
        STATE_LOW                    = 0x2,   
        STATE_HIGH                   = 0x4    
    };

    State & operator|=(State & a, const State b)
    {
        a = static_cast<State>(static_cast<int>(a) | static_cast<int>(b));
        return a;
    }

    State & operator&=(State & a, const State b)
    {
        a = static_cast<State>(static_cast<int>(a) & static_cast<int>(b));
        return a;
    }
     State & operator~(State& a)
    {
        a = static_cast<State>( ~static_cast<int>(a));
        return a;
    }


int main()
{
  State result = STATE_OK;

  result |= STATE_FAIL;    // ok
  result &= STATE_FAIL;    // ok
  result &= ~STATE_FAIL;    // fail

  return 0;
}

I get the following error:

In function int main(): Line 35: error: invalid conversion from int to State compilation terminated due to -Wfatal-errors.

Rama
  • 3,222
  • 2
  • 11
  • 26
sergio campo
  • 190
  • 2
  • 13
  • The casting of enums is in the other question but it does not show taking the argument by value and returning a value instead of references in the answer by @tuple_cat does for this question. This is important when creating a correct _bitwise NOT_ `operator~`. – snow_abstraction Feb 16 '17 at 19:41

1 Answers1

3

The error you're getting is caused by taking the parameter as a non-const reference (which cannot bind to temporaries, which the expression STATE_FAIL is).

Also there's something wrong in your operator~ implementation: e.g. your operator~ modifies the parameter which is not the usual conventional behavior of ~, as shown here.

This should work in the expected way, i.e. it doesn't modify its argument and only returns the result of the operation:

State operator~(const State a)
{
    return static_cast<State>(~static_cast<int>(a));
}
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • After playing around this example, it seems that having a non const `State &` as a parameter for `operator~` prevents it from being used. This answer is correct, you must get rid of the reference. – François Andrieux Feb 16 '17 at 19:13
  • Having a non-const ref as a parameter doesn't prevent the `operator~` from being used. As explained in the answer, it only prevents temporaries (rvalue expressions) from being passed as the argument, because rvalues cannot be passed as non-const references. – Emil Laine Feb 16 '17 at 19:20