Hacker News new | ask | show | jobs
by mikeash 4835 days ago
For me, and perhaps others, this is because C++ enshrines idiotic counter-intuitive operator overloading in its standard library.
1 comments

Examples ?
The use of << and >> for streams is the one that always comes to mind. So minor, and yet so awful.
Well this is clearly a matter of taste; the visual implication of movement (http://images.google.com/images?q=diversion+sign+chevrons) is quite elegant IMHO, and the precedence seems natural also. But others' mileage obviously varies ...
I disagree that the precedence is natural. Without looking it up, and without compiling it, what do the following (IMO quite reasonable in general) lines of code do?

    cout << x & y;
    cout << (x & mask) != 0;
    cout << boolVar ? "Yes" : "No";
As for the visual implication of movement, I have no objection whatsoever to using the << operator for stream operations in general. However, I strenuously object to doing this in a language which already defines them as bitshift operators. Repurposing an operator to do something completely different (and especially in this case, where a functional operator suddenly turns into one that's almost entirely about causing a side effect) is bad. Operator overloading can be useful and result in great, comprehensible code, but only if operators only mean the same thing everywhere.
Point taken, but small beer IMO; I use parens in boolean expressions because I can never remember the precedence of && vs ||, so would naturally use them here too.

And I don't buy the fact that << is somehow off limits because it's used for bitshift; the domain of usage is usually disjoint, although one would have to squint to grok the outputting of a bitshifted value to a stream - but how frequent is that?

Yes the << notation isn't perfect, but it is much nicer than named functions (and certainly superior to < (which Stroustrup initially considered)!). Adding arbitrary operators to the language would have required mechanisms to define associativity and precedence, which would have added a weight of complexity disproportionate to the reward.

I don't really see the big advantage to << over named functions here. Compare:

    cout << string << " and " << otherstring << endl;

    cout.write(string).write(" and ").write(otherstring).write(endl);
It's about as readable to me. To me, operator overloading is good when the meaning is already obvious because of shared context that everybody has. That's not the case when co-opting << for stream operators.