4

Some operators cannot be overloaded as class members. One such example are the bitwise shift operators used for streams see here for example. The reason for that (as far as I understand it) seems to be that the left hand site operand is the one you define the behaviour for and you cannot define behaviour for the built-in streams. Please correct me if I'm wrong.

I think it would be useful to define those overloads as class members, because they likely need to access private data. Sure, there's friend, but that seems to be more of a workaround.

Now this is more of a hypothetical question, but why not swap the meaning of >> and << then?

obj >> std::cout;
obj << std::cin;

This way, the whole operation happens from the point of view of the object, not the stream. The overload can be made as a member function, because the object is the left hand operand. Would that be possible?

I guess there are a lot of things this would break, like readability for starters as everybody is used to the other way. What other things would this break?

5

Operator overloads in C++ are syntactic sugar, nothing more. Your example will work fine: however, consider two things. First, how do people expect stream operators (technically bitshift operators) to function? They expect them to be able to be chained: the second idea to consider is how does your example work with chaining?

Given this code:

std::cout << obj1 << obj2 << std::endl;

What is really going on is this, once you remove the syntactic sugar:

std::cout.operator<<(obj1).operator<<(obj2).operator<<(std::endl);

Remember, operator<<() returns a reference to *this by convention (true in the standard library, and a good idea in general to allow chaining operators this way). That means that all of those calls are invoked on std::cout, the first object referenced in that statement.

Now consider your example:

obj >> std::cout;

If you extend this to chain multiple objects, you might get this:

obj1 >> obj2 >> std::cout;

Which would look like this if converted to proper function calls:

obj1.operator>>(obj2).operator>>(std::cout);

What this means is yes, you can reverse the order, but it will break down and not behave the way C++ programmers expect once you chain multiple functions together.

| improve this answer | |
  • Espectially since for obj1.operator>>(obj2)... your class needs a class member operator >> for every single other type that can ever exist, ever. – Jerry Jeremiah Oct 30 '16 at 22:03
  • @JerryJeremiah Or a template one. – user253751 Oct 31 '16 at 22:13
3

Swapping the direction of the I/O operators to move the operands to the left-hand side would be technically possible, but the "chaining" which is often used for I/O streaming would be at least cumbersome. Instead of

std::cout << "The result is " << result << endl;

you would have to write either

"The result is " >> std::cout;
result >> std::cout;
std::endl >> std::cout;

or

std::endl >> (result >> ("The result is " >> std::count));

which feels unnatural.

| improve this answer | |
1

Along with the problems already cited (which mostly boil down to lack of chaining), you have another fundamental problem here. Consider what happens if you try to work with a type that's built into the compiler:

int x;

x << std::cin;

Lacking a free function overloaded to do the job, this would be trying to do x.operator<<(std::cin);. Since x is of type int, it doesn't and can't contain any overloaded operators.

So, for all the built-in types, you'd still have to implement the overload as a free function like you do now, or else build wrappers like Java's Integer just to handle these overloads. Neither seems (at least to me) to provide any meaningful improvement over the current situation.

| improve this answer | |
  • This is a good point because it addresses the "overload in a method" (member of a class) aspect of the question, because not everything is a class. – null Oct 31 '16 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.