<optional<bool>
>следует использовать с особой осторожностью и вниманием.
Во-первых, он функционально похож на трисостояние булевое (ложное, может быть, истинное) — например,boost::tribool— за исключением того, что в трисостоянии булевое состояниепредставляет собой действительное значение, в отличие от соответствующего состояния неинициализированного<optional<bool>
>. Следует тщательно рассмотреть, действительно ли требуется<optional<bool>
>вместо<tribool
>.
Во-вторых, хотя<optional<>
>обеспечивает контекстное преобразование в<bool
>в C++11, это возвращается к неявному преобразованию на старых компиляторах. Это преобразование относится к состоянию инициализации, а не к содержащемуся значению. Использование<optional<bool>
>может привести к тонким ошибкам из-за неявного<bool
>Преобразование:
void foo ( bool v ) ;
void bar()
{
optional<bool> v = try();
foo(v);
}
Единственная неявная конверсия —<bool
>, и она безопасна в том смысле, что типичные интегральные рекламные акции не применяются (то есть, если<foo()
>вместо этого принимает<int
>, он не будет компилироваться).
В-третьих, смешанные сравнения с<bool
>работают иначе, чем аналогичные смешанные сравнения между указателями и<bool
>, поэтому результаты могут вас удивить:
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
if (oEmpty == none);
if (oEmpty == false);
if (oEmpty == true);
if (oFalse == none);
if (oFalse == false);
if (oFalse == true);
if (oTrue == none);
if (oTrue == false);
if (oTrue == true);
Иными словами, для<optional<>
>следующее утверждение не выполняется:
assert((opt == false) == (!opt));