1

This code below shows how to overload the << operator for an enum type. (Taken from here).

days operator+ (days d)
{
    return static_cast<days>((static_cast<int>(d) + 1) % 7);
}

ostream& operator<< (ostream& out, days d)
{
    switch(d)
    {
        case SUNDAY: out << "SUNDAY"; 
        break;
        case MONDAY: out << "MONDAY";
        break;
        case TUESDAY: out << "TUESDAY";
        break;
        case WEDNESDAY: out << "WEDNESDAY";
        break;
        case THURSDAY: out << "THURSDAY";
        break;
        case FRIDAY: out << "FRIDAY";
        break;
        case SATURDAY: out << "SATURDAY";
        break;
    }
    return out;
}

The above code can ostensibly be used in the following way:

int main()
{
    days aDay = SUNDAY;
    cout << +aDay << endl;

    return 0;
}

It is clear that the intent here is to overload the << operator, for use on the enumurated type days. Eventually, we will use it as: cout << aDay << endl;

What I do not understand, is how/where we are inputing the out stream. I can understand that a day object is being input into the << since its on the right side, but I do not see where the out object is being input... there is only one thing on the right hand side here...

Thank you.

Spacey
  • 2,941
  • 10
  • 47
  • 63

2 Answers2

1

The ostream& operator<< (ostream& out, days d) function is not meant to be called directly by you in your code. Instead, by defining that function, you are telling the compiler "Here's a function that implements the << operator for passing a days object to an ostream object." The compiler then implicitly generates a call to the operator<< function whenever you do something like cout << aDay << endl;. The cout object is an instance of ostream (or a child class thereof).

Mike Holt
  • 4,452
  • 1
  • 17
  • 24
  • Thanks Mike. I guess I am not clear why we need to pass in out into that function though. Why not just pass in `d`? – Spacey Jul 16 '14 at 18:56
  • It's simple. You want to be able to pass `d` to `cout` via the `<<` operator. There are thus two objects involved: the item you want to pass, and the `ostream` you want to pass it *to*. Therefore, any function you write in order to implement that functionality *needs* to know *which* `days` object you want to pass, **and** which `ostream` you want to pass it to. I'm really not sure where the confusion lies here. – Mike Holt Jul 16 '14 at 19:00
  • (New to operator overloading, so please bear with me). I get that part. What I do not understand is where-I-actually-passed-in-cout. `cout` is to the left of `<<`, while `d` is to the right of it. Yet both are passed into `<<`. I dont know. Maybe thats just the way it is? What if we wanted to pass in 3 arguments into `<<`? – Spacey Jul 16 '14 at 19:03
  • You can't have more than 2 parameters because << is a binary operator. And you can only override unary and ternary operator in C++. You can read Wikipedia for the complete list: https://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B – NoDataFound Jul 16 '14 at 19:06
  • @Learnaholic You're conflating two different types of syntax and asking why one doesn't look like the other. The first is expression syntax, and the second is function call syntax. The compiler knows how to *translate* one syntax to the other (i.e., from `cout << aDay` to `operator<<(cout, aDay)`), but that doesn't mean they need to look the same, nor *should* they look the same. So yes, that's just the way it is. – Mike Holt Jul 16 '14 at 19:42
  • @MikeHolt Ok, that was what was confusing me. Thanks! – Spacey Jul 16 '14 at 19:42
  • @Learnaholic Remember, *the whole point* of operator overloading is to be able to use objects in expressions, which allows for a more compact and readable syntax, and let the *compiler* figure out the underlying function call sequence for you. Thus, when you overload an operator, that translation from expression syntax to function call syntax is precisely what you're asking the compiler to do for you. – Mike Holt Jul 16 '14 at 19:42
1

Don't forget you can always use parenthesis -> cout << +aDay << endl -> (cout << +aDay) << endl.

And the compiler does the rest about finding an operator overload that matches std::ostream, days parameters like Mike Hots says.

NoDataFound
  • 11,381
  • 33
  • 59
  • Hmm... but do we *need* to pass in the first `out` argument? Why do we have to pass it in? Why not just pass in `d`? – Spacey Jul 16 '14 at 18:59
  • Think of it as an handler for the operator << : it needs to know both operand to work on. - In your first operator overload (days operator+), you have an instance method. - In the second operator overload (with <<), you don't have an instance method, but the method still needs to know with operand (aka: cout and aDay) it works on. – NoDataFound Jul 16 '14 at 19:01
  • Ah ok, that makes sense... Ok. The last part that confuses me then, is how/why the first argument into '<<' is to the left of it, while the second input argument is to the right...is that just the way it is? What if we wanted to pass in 3 arguments to the overloaded `<<` operator? thanks! – Spacey Jul 16 '14 at 19:05
  • @Learnaholic : read my other comments below ;) – NoDataFound Jul 16 '14 at 19:11