There's a persistent claim that people keep repeating over and over
like parrots about the usage of the bit shift operators with streams
being confusing.
I have been programming in C++ both as a hobby and professionally for
the past 15 years, and I have yet to encounter and actual case where it
wasn't 100% clear which type of operator was being used.
I personally don't think it is so much a matter of being confusing, so
much as "kind of ugly looking" and "doesn't particularly have convenient
fixed-formatting options".
for example, it is nice to be able to easily specify how many characters
a string or number will take up such that everything is lined up nicely
in the output, ...
actually, I would personally like more formatting options, as the
current options are a little sparse and require some manual treatment.
examples: printing output with variable indentation (take argument and
print that many spaces or tabs), ability to use certain POSIX
extensions, ability to print a string automatically adding quotes and
character escapes, ...
maybe also a less brain-damaged "sscanf" variant would also be nice
(IOW, one capable of dealing with CSV and other data, with the kind of
character following the type indicating what is to be regarded as the
terminator, and maybe with some mechanism to specify regexes, ...).
(It's extremely difficult to even artifically create code that makes
sense and could equally well be interpreted as bit-shifting or using
C++ streams. "a<< b" is a no-op if done with integrals so it alone
doesn't make sense. Conversely, streams are not assignable. Also, the
code would have to hide the actual type of those variables. This means
that the code would have to be eg. templated, and named in such a
deliberately confusing way as to not make clear what its functionality is.
In principle you could do something like "if(a<< b)" and it perhaps could
be sensible as both types of operation, but then you would have to quite
artificially and carefully craft the surrounding code to also be sensible
for both situations. In short, it's actually very difficult to even
deliberately make code so obfuscated as to make it unclear which operator
is being used.)
not much to say on this, not seeing "confusion as the main issue".
granted, there aren't all that many other good options, given C and C++
both have relatively weak varargs (which don't themselves preserve type).
yes, variadic templates may allow better options, assuming timely
adoption of C++11.
Java originally used '+' for everything, but later also added a
"printf()" style interface ("System.out.printf" and similar).
C# was more like "time for a pile of overloaded methods"
(Console.WriteLine, ...).
for my own language currently I mostly just adopted printf (along with
"println" and similar), but the language allows more options than C
would (such as a type for allowing any arguments to be automatically fed
through "toString", ...).
I am also "on a fence" regarding adopting the rest of stdio as the file
API (but likely using a different VFS internally, vaguely sort of like
in Cygwin). there are various possible options and tradeoffs.