Having to declare "global friend operator overloading" to do serialization always struck me as kludgey. It didn't seem foundational to have to declare serialization operators outside of your class. So I was looking for a solid answer for why.
(Note: If anyone has better Google-Fu to find a good answer already written, I'd be interested to read that.)
What I suspect is that it's technically possible, and is only a notational issue. Had the library been designed to do member overloads of <<
and >>
, you'd have to build a line of streaming operations from right to left, instead of left to right. So instead of writing:
Rational r (1, 2);
cout << "Your rational number is " << r;
You would have to write the output line as:
r >> ("Your rational number is " >> cout);
The parentheses are needed to kick off the backwards chaining, because >>
and <<
associate left-to-right. Without them, it will try to to find a match for r >> "Your rational number is "
before "Your rational number is " >> cout
. Had an operator with right-to-left associativity been picked, this could be avoided:
r >>= "Your rational number is " >>= cout;
(Note: Inside the library, non-class types like the string literal would have to be taken care of with global operator overloads.)
But is that the limit, and this reversal is pretty much inevitable for any iostream-style design that wanted serialization dispatched into the class? Am I missing any other problems?
UPDATE Perhaps a better phrasing of the "issue" is to say that I came to suspect the following:
For non-stream objects that wish to serialize themselves, the iostream library COULD hypothetically have been designed so that inserters and extracters were class members instead of global overloads...and without (significantly) affecting the runtime properties. Yet this would have ONLY worked if the iostream authors were willing to accept it would force clients to form streaming operations right-to-left.
But I lack an intuition about why global overloading an operator vs. a member could unlock an otherwise-unlockable ability to express oneself left-to-right (instead of right-to-left). Question is whether hindsight, or templates, or some esoteric feature of C++11 could offer an alternative. OR does "C++ physics" have an inherent bias for one direction over another, and global overloading is somehow the only compile-time trick in the book for overriding it.
Compare with Fleming's left hand rule for motors