c++operator-overloadingpass-by-reference

Why return the Month object from this operator overloader function?


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 :)


Solution

  • 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);       
    }