overloading operators for I/O
Don Clugston
dac at nospam.com.au
Wed Feb 14 23:38:34 PST 2007
Walter Bright wrote:
> 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.
I agree. There's another problem -- it really doesn't scale well. With
printf, you can do "%3.5f" to print a floating point number with a given
precision. With <<, that same operation is really horrible.
I'd like to see a couple more clarifications in the spec, wrt operator
overloading:
* If both opAddAssign and opAdd are provided, the compiler is permitted
to replace expressions of the form a = a+b; with a+=b; (that is, a+=b
_must_ mean a=a+b). And similarly for the other operators.
It's just insanity to make a+=b mean anything other that a = a + b.
Incidentally, this would make my 'operator overloading without
temporaries' proposal a non-breaking change.
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