<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));