The worst is probably the original idea to overload the bit shift operators for stream I/O, something which never really caught on outside the standard library.
The worst is probably the original idea to overload the bit shift operators for stream I/O, something which never really caught on outside the standard library.
The code was a simulation of a parallel system with multiple services that sent messages between them, or something like that. Instead of using serviceA.send("hello",serviceB) you had something like serviceA >> "hello" >> serviceB.
I really loved that (my classmates not so much)
throw exceptionC() << "error code: " << t;
I often found myself having to format error strings for exceptions, so I thought I could just do it like cout in one line. I know now this is bad for i18n strings.
throw exceptionC("error code: ", t);
?Ever since perfect forwarding I've been using this pattern to get out of arrow hell:
template <typename Arg, typename...Args>
string to_string(Arg &&arg, Args &&...args) {
stringstream buf;
buf << arg;
((buf << std::forward<Args>(args)), ...);
return buf.str();
} SinOsc b => Gain g => BiQuad f => dac;
https://chuck.stanford.edu/doc/language/oper.html#chuck[0] https://www.boost.org/doc/libs/1_78_0/libs/spirit/doc/html/s...
For example how would you implement std::function without overloaded operator()?
Also lambdas are defined in term of structs with overloaded operator ().
Without overloading, the standard could still ad-hoc define the specifications of lambdas and std::function, std:: ref, etc, but the language would be worse off.
To be mildly pedantic, printing in a destructor is horrible practice because stdout/stderr might be pipes or sockets and writing might fail. It's a really bad idea to do anything in a destructor that effects anything but the class being destroyed for those reasons, and when you get an error, it shows up as an opaque exception or trace or hang at the end of a scope instead of where it actually mattered.
MFC extends this idea to network programming, allowing the use of shift operators to send and receive data.
In the case of ostream and operator<<, this pattern reduces the number of intermediate objects that would otherwise be constructed.
If you object to iostream on religious or stylistic grounds, there's always fmt which is more like Go or Python string interpolation.[0]
No I object to it on usability grounds. It took more than 30 years for the committee to admit it but C++ now has typesafe std::print/std::format finally, after admonishing programmers for using `printf` in C.
Iostreams have a lot of issues, but overloading<< is a very minor one.