#include <optional>
bool f() {
std::optional<int> opt;
return opt;
}
Не компилируется: 'return': cannot convert from 'std::optional<int>' to 'bool'
Консультационная справка Я бы подумал найти объяснение, но я прочитал его, как должно быть в порядке.
Неявные преобразования выполняются всякий раз, когда выражение некоторого типа T1 используется в контексте, которое не принимает этот тип, но принимает некоторый другой тип T2; в частности:
- когда выражение используется в качестве аргумента при вызове функции, объявленной с параметром T2;
- когда выражение используется в качестве операнда с оператором, который ожидает T2;
- при инициализации нового объекта типа T2, включая оператор return в функции, возвращающей T2;
- когда выражение используется в операторе switch (T2 является целочисленным типом);
- когда выражение используется в операторе if или цикле (T2 - bool).
operator bool()
изstd::optional
этоexplicit
.Ответы:
std::optional
не имеет возможности для неявного преобразования вbool
. (Разрешение неявных преобразованийbool
обычно считается плохой идеей, посколькуbool
это целочисленный тип, поэтому что-то вродеint i = opt
бы скомпилирует и сделает совсем не то, что нужно.)std::optional
действительно есть «контекстное преобразование» в BOOL, определение которого похоже на оператор литого:explicit operator bool()
. Это не может быть использовано для неявных преобразований; он применяется только в определенных конкретных ситуациях, когда ожидаемый «контекст» является логическим, например, условие if-оператора.То, что вы хотите
opt.has_value()
.источник
Из документов C ++ :
Читайте о контекстных конверсиях здесь :
Вы можете сделать следующее взломать:
потому что контекстное преобразование происходит в случае встроенных логических операторов, но контекстное преобразование не включает в себя
return
операторы иstd::optional
само по себе не имеет неявного преобразования вbool
.Поэтому было бы лучше использовать
std::optional<T>::has_value
:источник
return {opt}
? илиreturn bool{opt};
return {opt};
не будет работать , ноreturn static_cast<bool>(opt);
иreturn bool{opt};
будет работать. Тем не менее, предлагается использоватьhas_value
функцию-член, потому что она действительно показывает четкое намерение того, что вы хотите сделатьreturn !!pot;
хак (has_value
лучше)Это связано с тем, что неявное скрытие std :: option для bool не поддерживается: https://en.cppreference.com/w/cpp/utility/optional/operator_bool
Вы должны явно преобразовать в bool как
bool(opt)
или просто использоватьopt.has_value()
вместо этого.источник
Дело не в неявном преобразовании, а в типе инициализации.
Что необязательно, так это явная функция преобразования, т.е.
От N4849 [class.conv.fct] / p2
Вышеуказанное означает, что в этих случаях будет использоваться функция преобразования: [dcl.init] / p16
Однако в этих случаях не будет использоваться функция преобразования: [dcl.init] / p15
Пример в вопросе относится к случаю инициализации копирования и не использует опциональную функцию преобразования.
источник