Today I want to share with you something that really surprised me. Currently, Tomasz Kamiński and Ville Voutilainen are working on fixing a certain issue with `std::optional`

’s converting constructors (which deserves a separate post). At some point, in the solution, they perform the following type-trait test:

is_constructible<T, U>::value || is_convertible<U, T>::value

If the varying order of `T`

and `U`

upsets you, rest assured that this is correct. This is how these traits are defined: `is_constructible`

takes the created type first, whereas `is_convertible`

takes the converted-to type second. But what really struck me here is the apparent redundancy. When type `U`

is convertible to `T`

does it not imply that `T`

is constructible from `U`

? Or in other words, if the following copy-initialization works:

T v = u;

The following direct-initialization:

T v (u);

should also work? Well, this is C++. It turns out that such expectation is not necessarily correct. Continue reading