2

When I first saw C++ years ago, I thought it was very strange how it used cout and << to print to the screen. As far as I'm aware, C++ is the only language that uses an operator to print to the screen, so it definitely stands out as unusual.

The operator isn't entirely inconsistent, as there are other streams that accept the << operator with similar semantics, plus you can usually "reverse" the operator to >> for cin and similar. It just seems odd to me (and a little obtuse) that an operator originally used to shift bits gained a very different meaning.

A few languages have operators that have side effects. Some languages use ! as a binary operator for passing messages, which may or may not have side effects, depending on the message being passed.

But the thing is: C++ could have used functions to accomplish the same purpose, and depending on who you ask, that would be much clearer in most cases.

What advantage is there in using an operator instead of a function?

I can see a possible rationale with type safety. It is an improvement over printf for that particular issue, at least. It's a lot less verbose than a bunch of calls to an overloaded non-formatted print function. But that's a pretty flimsy use case. You can't exactly look at a C++ source file if you've never seen C++ before and know that the couts print to the screen.

Beefster
  • 668
  • 6
  • 19
  • It's not a side effect. It's just another stream. The operating system may decide to print the stdout stream to the screen. – Kenny Ostrom Jan 10 '18 at 18:58
  • 3
    @freakish: No, the `< – Ben Voigt Jan 10 '18 at 19:42
  • @Ben Voigt Oh yeah. It didn't occur to me that += might make sense sometimes. Good point. – Beefster Jan 10 '18 at 20:01
  • 1
    A saner alternative probably would have been to use a template function to specialize for each type (similar to `std::hash`), but at the time probably the language missed half the features needed to make it work. – Matteo Italia Jan 10 '18 at 20:02
  • @MatteoItalia That would probably be a really bad idea for C++ since it would make a different template instantiation for each combination of parameters. (That is if I'm understanding you correctly and you're saying this would be something similar to printf). C++ needs type erasure or an Any type for this kind of thing to work sanely. Oh hey, C++17 has `any`... Except that cout is *much* older than that. – Beefster Jan 10 '18 at 20:12
  • @benvoight: `+=` associates to the right. I'm pretty sure Stroustrup mentions that in his discussion of iostreams in The C++ Programming Language. The problem with function calls is that they don't chain. Pre-template there was no way to write a type safe variadic function. – rici Jan 10 '18 at 20:15
  • @BenVoigt `the << operator is for bit-shifting` Let's be honest here: no operator exists for solely one purpose. But fair enough: this proves that even this is opinion based. Yet another reason for the question being unfit for SO. – freakish Jan 10 '18 at 20:17
  • @freakish: Why not use a function for that purpose though? Sure, there's already printf for that job, but it doesn't use any of the nice features from C++. On the other hand, it is very nice when operators used for multiple purposes have similar semantics. – Beefster Jan 10 '18 at 20:27
  • @rici: Don't be so sure. I can make `outconsole("var1 = ")(var1)(", var2 = ")(var2)(endl);` work in C++98 with no templates. It's just the Fluent Syntax pattern (returning a reference to `*this`) combined with `operator()` overloading. – Ben Voigt Jan 10 '18 at 21:09
  • @freakish: That's not "opinion-based" at all, it is section `[expr.shift]` of the C++ Standard (currently that section is number 8.8). The grammar production that makes `cout << blah;` work is named *shift-expression*. – Ben Voigt Jan 10 '18 at 21:12
  • 4
    Duplicate of: https://stackoverflow.com/q/4854248/103167 Too bad people rushed in with a totally wrong closure reason. – Ben Voigt Jan 10 '18 at 21:18
  • @BenVoigt: OK, that's true. But it is not exactly more readable :) (And my point about the associativity of `+=` stands.) – rici Jan 10 '18 at 21:18
  • @rici: Yes, the associativity of `+=` is wrong. Which is a *completely objective* reason not to use it. Nothing "opinion-based" at all; the close reason is ill-considered. – Ben Voigt Jan 10 '18 at 21:21
  • 2
    @rici: also, I'm pretty sure chained function calls would be a lot more readable, because now the format control parameters (field width, hex vs decimal vs binary, etc) would go in the same argument list with the variable they affect, instead of the current system of manipulator inserters. Breaking the limitation of two operands, one of which *must* be the stream, is a powerful thing. – Ben Voigt Jan 10 '18 at 21:23
  • @BenVoigt `30.7.5.1 Class template basic_ostream` and in that chapter operator << clearly defined as "inserter", not "shift". And the whole meaning explained there. There is no amibiguity on this topic in the standard. Plus the discussion is pointless. It's like asking "why do we use brackets for function calls?". Such opinion based (or philosophical or perhaps psychological) questions are not for SO. – freakish Jan 10 '18 at 21:51
  • @ben: if we were to continue the debate on `operator<>` vs. `operator()`, I fear it would undermine your claim that the answer is not opinion-based. As it happens, I don't have a strong opinion, but maybe Stroustrup did/does. It doesn't matter; the die is cast. When you or OP design your own languages, you can make and attempt to justify whateve decisions seem most adequate. I dragged out my copy of the BS text, and see no evidence that he even considered call syntax; from what I know, it would not have appealed to him even if he considered it... – rici Jan 10 '18 at 21:53
  • ... and, as a final comment, if you were to put controls in the same function call as the variable they modify, you would force every output override (for a user type) to implement every control, which would massively raise the implementation cost. (ImhO :-) ) – rici Jan 10 '18 at 21:58
  • @rici: IMO (and unlike the original question, this is an opinion) "format controls are not supported at all for new types that don't declare support" is a better state of affairs than "manipulators change the stream state which affects the first operation inside the user implementation but then the succeeding operations still inside the same user-defined `operator< – Ben Voigt Jan 11 '18 at 00:47

0 Answers0