This exists to support:
optional<int> o(42);
o = {}; // <== we want this to reset o
We have a bunch of assignment overloads, which take:
nullopt_t
optional const&
optional&&
U&&
optional<U> const&
optional<U>&&
For scalars, specifically, #4 would be a standard conversion whereas anything else would be a user-defined conversion - so it would be the best match. However, the result of that would be assigning o
to be engaged with a value of 0
. That would mean that o = {}
could potentially mean different things depending on the type of T
. Hence, we exclude scalars.
For non-scalars, #4 and #3 would be equivalent (both user-defined conversions), and #3 would win by being a non-template. No problem there.