
C++ Fun with(out) keyword explicit - ingve
http://arne-mertz.de/2015/03/fun-without-keyword-explicit/
======
Animats
This is why it's a rule in C++ that implicit conversions generate ambiguities
and error messages like that. In such ambiguous situations, one interpretation
has to be significantly "better" for it to be accepted without an error
message. This is better than silently picking one of the possibilities when
there's an ambiguity.

I would have thought that the no-conversion case (std::string vs std::string)
would clearly beat the conversion case (Annie vs Annie), but I'm not really
current on C++ conversion priority.

This sort of thing is why operator overloading isn't that great an idea. It
seems attractive at first, but it gets complicated fast. As a rule of thumb,
unless you're doing something mathematical, like matrices, for which the rules
are well understood, don't overload mathematical operators.

A classic in Python:

    
    
       (1,2) + (3,4) -> (1,2,3,4).  
    

But

    
    
       numpy.array((1,2)) + numpy.array((3,4)) -> array([4,6]).
    

This, combined with Python's lack of parameter type checking, can lead to
strange results if a library function is called with the wrong type of
numerical list object.

~~~
blub
If one has compile time safety, operator overloading is just fine though.

In this case I'm pretty sure this was a compiler bug, "no conversions" should
have priority over "conversions"

~~~
dietrichepp
Compile-time safety doesn't protect you from being stupid when you choose the
semantics of overloaded operators, just like compile-time safety doesn't
protect you from giving your functions stupid names. My hypothesis is that so
many C++ programmers abused operator overloading (even in the standard
library, e.g. the absurdity of <<) that it made language designers remove it
altogether from e.g. Java and many other languages.

~~~
blub
The argument against operator overloading can be reduced to "programmers can't
be trusted to design their classes properly".

And Java was exactly like that in the beginning, a language designed for the
average developer, giving them only the basics they could be trusted with.
Interestingly, Java's been busy adding back most of the things it decided
against. Wouldn't be surprised if they add operator overloading in a future
version.

<< is not IMO absurd, it makes streaming much nicer. The boost serialization &
operator is however the kind of overloading that gives one pause when they see
it.

~~~
dietrichepp
Basically, for human-readable output << is far inferior to the alternatives
that came before it and after it, and from an API perspective has nasty warts
both in syntax and semantics.

* C's printf() is superior because it can be localized.

* Later formatting functions like Python's .format(), C# String.Format(), and C++ fmt::format() (from cppformat library) are far superior in normal use cases: they can be localized but they don't suffer from printf() safety problems.

* << suffers from severe problems in terms of syntax because it sits between arithmetic and comparison operators in precedence. So you can std::cout << x * 5; but you cannot std::cout << x & 0xff;

* iostream also suffers from the curse of statefulness. Unlike other formatting functions, changing the precision you want to use changes the properties of the IO stream itself, which is nonsensical. Either the properties should be bundled with the number or they should be lexically scoped.

Maybe << is nice for one or two things, but for the bread and butter of what
developers do, it's absolutely terrible. I don't know how it makes "streaming
nicer" because I'm not sure what you mean by streaming—the word has a few
different possible contextual meanings, and I can't imagine how << makes any
of those any easier.

The worst part of this is that they could have just used function call syntax
and two of the major usability problems would have instantly disappeared. It
would avoid problems with precedence and it would allow you to pass additional
precision parameters.

Unfortunately, localization is really a hard (as in non-negotiable)
requirement, and since << is so terrible at it, you are often forced to rip
its usage out of a program rather than just work around it.

~~~
blub
Sure, << has these problems and for more advanced use cases one can use Boost
or the library you mentioned. For localization one has to use a non-STL
solution anyway, because the supporty is rudimentary in the standard lib.

On the other hand, there's nothing easier than using << for logging and
concatenating + optionally converting strings and other types.

All in all the only real problem caused by << being an operator instead of a
function is the precedence one; the rest are API design issues I would argue.
Luckily it's a compiler warning (unused value) and if one adds another output
op to the chain it will most likely be a compile error or still a warnig. So I
still don't see why we have to condemn operator overloading because of <<.

------
dgemm
Implicit casts are the worst feature of C, and C++ manages to make things even
worse with implicit conversions by default. Marvelous.

I should create a new subset of C++ and call it C += 0.5.

------
echelon
The choices made by C++ are some of the reasons why I am so happy that Rust
exists.

------
72deluxe
I put the default constructor in private and mark the constructor I want
everyone to use (typically the only one) as explicit. Seems safer than
implicit conversions.

------
oselhn
In C++11 you can even have implicit conversion for multiple args constructors.
But it is harder to use unintentionally than single argument implicit
conversions.

------
mappu
I wonder which compiler it was?

~~~
blub
Embarcadero C++ 2010, formerly known as Borland C++.

~~~
cheez
FWIW, their latest incarnation uses Clang as a front-end for at least the
64-bit version.

