Потому что при таком преобразовании происходит неявное преобразование std::optional<int>(0)
в bool
. А в документации ясно говорится, что такое преобразование дает true
, если в std::optional
хранится значение, и false
, если его нет. Но ведь в std::optional<int>(0)
значение хранится, с этим вы не спорите? Вот и получается, что его приведение к bool
дает значение true
, все в соответствии со стандартом...
Если хотите получить значение, то делайте уж
const auto b = std::optional<bool>(*a);
только при использовании оператора *
обратите внимание на примечание
This operator does not check whether the optional contains a value! You can do so manually by using has_value() or simply operator bool(). Alternatively, if checked access is needed, value() or value_or() may be used.
P.S. Мне показалось правильным внести в ответ из комментариев следующее:
Если в первом заменить тип int
на bool
, то будет ожидаемый вывод. Если поставить в первом int
, а во втором double
, то тоже будет ожидаемый результат, хотя при этом типы разные.
Потому что нет оператора преобразования optional<int>
в double
, только в bool
. Соответственно, рассматриваются варианты, требующие более сложного преобразования.
<bool> -> <bool>
- работает точно соответствующий конструктор копирования.
<int> -> <bool>
- работает приведение типа к bool
, о котором я уже написал.
<int> -> <double>
— ничего проще, чем шаблонный конструктор, нет, применяется он.