overloading operators for I/O
Walter Bright
newshound at digitalmars.com
Wed Feb 14 13:24:36 PST 2007
Michiel wrote:
>> And we should keep on frowning on attempts to use overloaded << for I/O
>> purposes <g>.
>
> Why? I think it's intuitive. The arrows point from the source of the
message to
> the destination. Should the operator only be used for shifting
because that
> happens to have been its first purpose?
>
> I also like how you can send a message to an abstract object. And
that can be a
> cout, a cerr, an error console in a GUI, or something else. Same
thing the other
> way around.
Good question. C++ conventional wisdom is that's great, because it's
always been done that way in C++. Few question it.
Let's step back a bit. Suppose I overload '+' to be "launch nuclear
missiles." You see some code:
x = a + b;
and what do you think? I think "add a and b, assign the result to x",
but instead, nuclear missiles are launched. It is completely unexpected
and unintuitive for '+' to mean anything other than 'add'. To do
something completely unrelated to 'add', one should instead write:
x = launchNuclearMissiles(a, b);
where the meaning is plain, or at least, one isn't assuming it's adding
a and b.
So why overload operators at all? For the purposes of implementing UDTs
(User Defined Types) that have legitimate arithmetic operations on them,
such as matrices, extended precision numbers, etc.
Now back to '<<' and '>>'. To me, they are arithmetic operators, and
mean shift left and shift right. Shift is not an I/O operation. To say
they are intuitive is not because they are, but because C++ users are
simply accustomed to it.
a << b << c << d;
That doesn't scream I/O to me. And if a, b, etc. are non-trivial
expressions, they wind up:
1) interacting with the operator precedence of << in unfortunate ways
2) suppose you want to print a variable shifted left by a few bits:
a << (b << 3) << c << d;
blech.
3) Suppose you've got some relational operators and templates thrown in:
a << b<c<3>> << c < d << e;
and things just go downhill from there.
4) Operators aren't very greppable, meaning it's hard to go grepping
through source code looking to see if << has been overloaded.
5) The Spirit library for C++ uses operator overloading to create a
specialized DSL for specifying grammar. The trouble is, the code looks
exactly like regular C++ expressions (since new operators cannot be
defined, nor can operator precedence be changed), and there are some big
warning boxes that the resulting appearance may LOOK like C++ but is
about as far removed from it as one can get. This doesn't enhance
readability.
And to sum up:
writefln(a, b, c, d);
seems pretty intuitive to me. There's just no advantage to overloading <<.
More information about the Digitalmars-d
mailing list