0

I can globally overload unary + and - operators like this:

#include <cstdint>

enum local_states_t
{
    LOCAL_STATE_A = 1,
    LOCAL_STATE_B,
    LOCAL_STATE_LIMIT,
};

typedef uint32_t state_type_t;

state_type_t operator-(local_states_t state) { return static_cast<state_type_t>(state | (1<<31)); }

Can I do the same for prefix ++/--? The problem here of course is how would the compiler know that it only needs to call these functions for local_state_t - types? Prefix operators don't have a dummy value..

glades
  • 3,778
  • 1
  • 12
  • 34
  • `(state | (1<<31))` looks suspicious. I think you want to pull that outside the parenthesis, and make it `| 1UL<<31` – MSalters Mar 08 '22 at 09:20
  • Can you show what you tried? Because I don't yet see the problem. – MSalters Mar 08 '22 at 09:21
  • @MSalters: I want to overload prefix ++ to return a "flagged" uint32 (mark highest 3 bits with certain properties). I can do it with unary +/- but can I do it with ++/-- as well (prefix)? – glades Mar 08 '22 at 13:15
  • Prefix `operator++` by convention changes its argument, i.e. an `local_states_t&` for your overload . You can't add `1<<31` to `local_states_t` since that is out of range. So that's why I don't see what you're trying to achieve. Overloading itself isn't the problem - compilers know how to call the right operator for a given argument. – MSalters Mar 08 '22 at 13:33
  • @MSalters: Isn't enum = int? It would indeed cause an overflow but wouldn't the bit be set anyway? If I don't care about representation, does it matter if i take int over uint? But anyway, what would the operator overload for ++/-- look like? – glades Mar 08 '22 at 13:44
  • No. You can write `enum local_states_t : int` to fix the **underlying type**, but even then it's not exactly the same type as `int`. (And technically you need `long` for `1L<<31` but we'll overlook that). And I'd expect the overload to be declared as `local_states_t& operator++(local_states_t &);` – MSalters Mar 08 '22 at 13:47
  • @MSalters: Ahh, so the overload is determined by being the return value of the ++ being a reference to the input object? But why did you use local_states_t& inside the brackets? Isn't that indicating postfix ++? Interesting info on enum! So when I make the underlying type uint32_t will it work then? – glades Mar 08 '22 at 13:50
  • No, overload resolution as always is determined solely by the argument type. The **postfix** `operator++` is the one with a dummy: `local_states_t operator++(local_states_t &, int);`. Note the missing `&` on the return type. An underlying type of `unit42_t` is indeed enough to add `1<<31`, or you could just add a `LOCAL_STATE_FLAG==1L<<31` to the declaration – MSalters Mar 08 '22 at 13:55
  • @MSalters: Right, thank you! I didn't grasp that the local_states_t parameter would appear in the overload at all, as it doesn't for class method operator overloads. But I can then go against the convention and use state_type_t as my return type as well ++ right? – glades Mar 08 '22 at 13:58
  • Convention is for humans; your compiler won't complain about the return type. – MSalters Mar 08 '22 at 14:00
  • @MSalters: I think that solves it. Thank you for your help! – glades Mar 08 '22 at 14:04

1 Answers1

1

(From the comments)

Yes - you can define local_states_t& operator++(local_states_t &). Unlike classes, enums can't have members, so you need a free function.

You can also define it to return state_type_t, which is unusual but allowed.

MSalters
  • 173,980
  • 10
  • 155
  • 350