I was reading Bjarne Stroustrup's "Principle and Practice using C++". In chapter 9.6 about operator overloading, he gives the following example of defining the incrementing operator ++
for the enum class Month
:
enum class Month {
Jan=1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
};
Month operator++(Month& m) // prefix increment operator
{
m = (m==Month::Dec) ? Month::Jan : Month(static_cast<int>(m)+1);
return m;
}
He then says it could be used like this:
Month m = Month::Sep;
++m; // m becomes Oct
++m; // m becomes Nov
++m; // m becomes Dec
++m; // m becomes Jan (“wrap around”)
But, I don't understand the point of returning a Month
when you pass the Month
object by reference and change it. Why not write the function like this?
void operator++(Month& m) // prefix increment operator
{
m = (m==Month::Dec) ? Month::Jan : Month(static_cast<int>(m)+1);
}
The code ran fine when I tested. I am wondering what I have overlooked since this Stroustrup guy knows the language quite well :)
When you override operators, you're supposed to override them in the expected fashion.
You probably tested something like:
Month month = Month::SEP;
++month;
But, what happens if you try to do something like this?
Month October = ++month;
This should be a legal operation, but your operator++()
method returns void
, so it won't work properly.
The return from the operator++()
method needs to return a reference to the object, because people will use ++foo
in an expression, including expressions that may modify the object.
Hence, your function signature should be:
Month& operator++(Month& m)
{
return m = (m==Month::Dec) ? Month::Jan : Month(static_cast<int>(m)+1);
}