Question

I am learning C++ and have never dealt with streams. I would have expected the notation to be:

std::cout << "foo";
char foo << std::cin;

I'm sure there's a good reason it is std::cin >> foo. What is it?

Was it helpful?

Solution

It has to do with the associativity of the << and >> operators.

They were originally only for bit shifting where they are left associative. The operator associativity remains the same when overloaded (otherwise, the code would be impossible to parse):

If you did

 int a, b ;
 a << b << cin

you'd get

(a << b) << cin

A bit shift and and input

This is why the standard library does it the way it does.

OTHER TIPS

a << b and a >> b are just shorthands for:

operator<<(a,b)

and

operator>>(a,b)

(or the member-function equivalents).

That is, they are just calls to particular functions. It just so happens that the C++ standard library overloads operator<< to perform output streaming to ostreams, and operator>> to perform input streaming from istreams.

These functions are only overloaded to have the stream on the left.

There are two reasons for this decision. The first is notational simplicity (that is, since there is only one way of ordering the operands, there is less ambiguity about the meaning of any particular code, and there is less need to implement huge numbers of different overloads when extending the standard library to support an additional class). The second is that << and >> are left associative, and so:

int a, b;
a << b << cin;

would become:

(a << b) << cin;

while:

int a, b;
cin >> b >> a;

correctly becomes:

(cin >> b) >> a;

It's so you'll be forced to put the console on the left the way god intended! :)

It actually has to do with something called operator overloading. If you're just learning C++ you probably haven't covered that yet so file what I'm about to say under "stuff I'll get later".

C++ lives on top of C. In C << and >> are just bit shift operators. In c++ it can be more. std:cout << foo is NOT C, it's C++. The reason it's C++ is because the std::cout object overloads the << operator to mean something other than bit shifting.

In other words, << only means send foo to cout, because cout said that's what it means. << is, in effect, a function on the class cout.

It's almost as if you said std::cout->sendThatToMe(foo).

In this whole affair foo is just a hapless parameter along for the ride that has no say over what << means. THAT is why you can't do it the other way. If you did it would be as if you were saying this:

foo->sendMeToThat( std::cout).

Which can be made to work IF you add that function (well the >> operator really) to every stinking object you might ever want to send to the console. Oh and good luck pulling it off with primitives.

So while I think there are very good style reasons to want to keep the console stuff on the left there actually is a technical reason it has to be that way. It's because operators being overloaded are already left associative. They have been since they were used to shift bits in the old C days. Overloading them doesn't offer a chance to change their associativity.

Thats just the way they are supposed to work. I think this was done to clearly differentiate input operations ( >> ) from output operations ( << ).
If you overload the << operator in this fancy way (As Captain Obvious suggested in comments):

template<typename T>
std::istream& operator<<( T& data , std::istream& is )
{
    is >> data;
    return *this;
}

It will be less clear if the operaton was input or output (With std::cin std::cout its easy, but thing about two streams named file1 and file2, one for reading and one for writting):

a << std::cin;
std::cout << a;

a << file;
file << a;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top