Reputation: 123
This is what I tried, but I see that overloading only increments the variable if I assign it to another variable. I.e, The value of the variable on which I do the increment does not increase. So, in the example below variable newDay
is THU but currentDay
remains WED.
How do I define the overload operator to increment variable I am doing the operation on?
typedef enum days {MON, TUE, WED, THU, FRI, SAT, SUN} days;
inline days operator++ (days& d) {
return static_cast<days>((static_cast<int>(d) + 1) % 7);
}
int main(int argc, const char * argv[]) {
days currentDay = WED;
days newDay = ++currentDay;
cout << "Current day: " << currentDay << ", Stored day: " << calendar[0] << ", New day: " << newDay << endl;
}
Upvotes: 6
Views: 7366
Reputation: 67224
First, I wouldn't recommend you overload operator++
to have the enum cycle.
This could easily cause a hang if you have a loop like:
for( days d = MON; d <= SUN; d++ ) {
// hangs
}
It's really unexpected in C++ that operator++
cycles. Consider using a C++ function like this, so it's 100% clear from the code that the enum
will cycle
template <typename E>
inline E& cycleEnum( E &val, E minVal, E maxVal ) {
int e = (int)val;
if( ++e > maxVal )
e = minVal;
return val = (E)e;
}
Use:
days day = MON;
cycleEnum( day, MON, SUN );
I have seen this done with a macro before
This only defines pre & post increment, but you could define bitwise ops too (though you probably shouldn't define increment and bitwise on the same enum class
)
#include <map>
#include <string>
using std::map, std::string;
enum class MouseButton {
Left,
Middle,
Right,
NUM_BUTTONS
};
#define PRE_AND_POST_INCREMENT( ENUM ) \
inline ENUM& operator++( ENUM& enumVal ) { \
return (ENUM&)(++(int&)enumVal); \
} \
\
inline ENUM operator++( ENUM& enumVal, int postIncrement ) { \
ENUM oldValue = enumVal; \
++enumVal; \
return oldValue; \
} \
PRE_AND_POST_INCREMENT( MouseButton )
map< MouseButton, string > mouseButtonName = {
{ MouseButton::Left, "Left" },
{ MouseButton::Middle, "Middle" },
{ MouseButton::Right, "Right" },
};
int main() {
for( MouseButton mb = MouseButton::Left; mb < MouseButton::NUM_BUTTONS; mb++ ) {
puts( mouseButtonName[ mb ].c_str() );
}
}
There is also this template
approach which you could adapt for operator++
(warning: it modifies all enum
s to act like an int
!)
Upvotes: 0
Reputation: 170065
If I modify your overloaded operator to this:
inline days operator++ (days const& d) {
return static_cast<days>((static_cast<int>(d) + 1) % 7);
}
It still compiles, despite the fact I added a const
specifier there. That's because you are not modifying d
like the semantics of prefix ++
demand.
So make sure you do modify it, if you want the operator to have the desired effect:
inline days operator++ (days& d) {
d = static_cast<days>((static_cast<int>(d) + 1) % 7);
return d;
}
Without commenting on the validity of your own design, note that it is a widely held opinion that prefix operator++
should return a modifiable lvalue, like the built-ins do. Bear in mind if you find yourself writing code like ++x = y
, you need to return a reference, i.e. date& operator++(date&)
.
Upvotes: 3
Reputation: 678
You defined the postfix operator. The normal behavior of the postfix operator is to increment the value of its argument but return the original value. It should behave like this:
days operator++(days& d,int){
days temp=d;
d=static_cast<days>((static_cast<int>(d) + 1) % 7);
return temp;
}
What you want is the prefix operator. This increments the value of the argument and returns a reference to its arguments. It should look like this:
days& operator++(days& d){
d=static_cast<days>((static_cast<int>(d) + 1) % 7);
return d;
}
Upvotes: -1