Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That's the perennial complaint and worry, but in my experience, people use operator overloading in C++ for mainly two things: function objects by overloading operator(), and iterators by overloading the dereferencing operators and increment operators.


At any given place, people use at most 30% of C++ features -- the bad thing is that these 30% subsets usually overlap only a little. People use operator overloading in C++ for all the crazy reasons, like I/O, for instance -- for even better (or maybe worse) examples, see boost, boost::lambda will be a good starting point.

Good abstractions are good, but operator overloading combined with templates and implicit casting is not one of them.


shrug

People always talk about it what can happen, but I've never seen instances of operator overloading in C++ that I objected to in a fundamental way.


iostream, for one. It's a real pain to deal simultaneously with this fancy bit-shift I/O syntax on the one hand, and i18n on the other -- fancy syntax is way inferior to format strings when you want to support multiple languages.

Also, please, take a look at the boost::lambda or other boost libraries -- they have large DSLs written on top of operator overloading which look nice when you look at them, but are terribly complicated to use and ridiculously hard to debug, thanks to the completely unintelligible messages that the compilers produce.

Most probable reason you've never seen it, is that most sane, experienced people know the danger and avoid it. When there's more than one person working on a project, it's way more important for the code to be easy to follow and debug than to look fancy.


I've made heavy use of Spirit, see: http://news.ycombinator.com/item?id=2912729

You are correct in that Spirit is difficult to debug, but that has nothing to do with operator overloading. That has to do with its extensive use of template metaprogramming and C++'s lack of concepts (http://en.wikipedia.org/wiki/Concepts_(C%2B%2B)). If they switched the whole library over to using named member functions, the debugging problems would still be there. And concepts would go a long way to preventing the compiler problems.

I've looked at boost::lambda, and decided it was mostly a novelty. How far towards a real lambada could you get without lambda support in the compiler? That far, it turns out, which was not far enough. The rules I had to remember to use it in non-trivial situations was more effort than it required to write a one-off function object. While I agree boost::lambda is more trouble than it's worth, I haven't seen or heard of terrible things happening because people used it.

I also think it's worth noting that many Boost libraries are purposefully on the edge of what is possible in C++. It's like a refereed sandbox for experimenting.

I've also had no problems with << and >> as the stream read and write operators. But, I also have no experience with internationalization. I don't see any obvious problems, though, what are they?

It's possible I've seen about the same amount of C++ as you (perhaps in some different areas) and come to a different conclusion.


While I agree boost::lambda is more trouble than it's worth, I haven't seen or heard of terrible things happening because people used it.

And this is precisely my point: nothing bad could happen because people haven't used it in serious projects, even though it is possible -- it's just more trouble than it's worth. This is actually the whole point of argument against operator overloading: it is troublesome for both implementors and users, and the value provided is minor - most people use operator overloading for math-like types (bignums, complex numbers, matrices) anyway. On the other hand, it requires (sometimes considerably) more work on the designers' and implementors' side, and more caution and experience on the programmer's side.

That said, I'm not against operator overloading myself. However, I'm heartily against operator overloading in C++, because it interacts really, really bad with other C++ features (especially implicit casting rules (which are bad anyway) and manual memory management). Please, see [1] for more information, it's explained better and wider there than I could do it here.

Regarding bit-shifting I/O, I've never figured out why they even thought it's a good idea at all. It isn't any more terse. If it's combined with output formatting it's much harder to figure out what's actually going to be written than with printf-like functions, because the formatting and expressions are mixed together. The only advantage I can think of is that it can be a little faster than parsing the format string every time. But still, you don't need to parse it every time. If the language design allowed it, they could have introduced something like CL's define-compiler-macro, but I think the utter mess created by presence of such tool in C++ would be overwhelming -- it's bad enough as it is, with template "metaprogramming" instead of real metaprogramming facilities.

The internationalization issues I mentioned make this completely useless: the usual way to support multiple interface languages is to use something like gettext for strings in code (see e.g. Qt Linguist for C++ implementation). Basically, for every string that's supposed to be user visible, you use a special translating function, i.e. instead of

printf("Hello, %s, it's %s!\n", name, day_of_week);

you write

printf(tr("Hello, %s, it's %s!\n"), name, day_of_week);

This simple approach does not map at all to the bit-shift I/O -- I'm fairly sure that experienced C++ hackers could create something along the lines of

cout << (translate << "Hello, " << name << ", it's " << day_of_week << "!\n");

but this is obviously useless because obviously not all (not even many) natural languages has syntactical structure of English. Better option would be:

cout << (translate("Hello, %{1}, it's %{2}!\n" << name << day_of_week);

but again, it's clearly only printf with unnecessarily convoluted syntax.

[1] -- http://yosefk.com/c++fqa/operator.html




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: