mirror of
https://github.com/boostorg/optional.git
synced 2025-07-16 05:42:07 +02:00
53 lines
1.9 KiB
Plaintext
53 lines
1.9 KiB
Plaintext
|
|
[section A note about optional<bool>]
|
|
|
|
`optional<bool>` should be used with special caution and consideration.
|
|
|
|
First, it is functionally similar to a tristate boolean (false, maybe, true)
|
|
—such as __BOOST_TRIBOOL__— except that in a tristate boolean, the maybe state
|
|
[_represents a valid value], unlike the corresponding state of an uninitialized
|
|
`optional<bool>`.
|
|
It should be carefully considered if an `optional<bool>` instead of a `tribool`
|
|
is really needed.
|
|
|
|
Second, although `optional<>` provides a contextual conversion to `bool` in C++11,
|
|
this falls back to an implicit conversion on older compilers. This conversion refers
|
|
to the initialization state and not to the contained value. Using `optional<bool>`
|
|
can lead to subtle errors due to the implicit `bool` conversion:
|
|
|
|
void foo ( bool v ) ;
|
|
void bar()
|
|
{
|
|
optional<bool> v = try();
|
|
|
|
// The following intended to pass the value of 'v' to foo():
|
|
foo(v);
|
|
// But instead, the initialization state is passed
|
|
// due to a typo: it should have been foo(*v).
|
|
}
|
|
|
|
The only implicit conversion is to `bool`, and it is safe in the sense that
|
|
typical integral promotions don't apply (i.e. if `foo()` takes an `int`
|
|
instead, it won't compile).
|
|
|
|
Third, mixed comparisons with `bool` work differently than similar mixed comparisons between pointers and `bool`, so the results might surprise you:
|
|
|
|
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
|
|
|
|
if (oEmpty == none); // renders true
|
|
if (oEmpty == false); // renders false!
|
|
if (oEmpty == true); // renders false!
|
|
|
|
if (oFalse == none); // renders false
|
|
if (oFalse == false); // renders true!
|
|
if (oFalse == true); // renders false
|
|
|
|
if (oTrue == none); // renders false
|
|
if (oTrue == false); // renders false
|
|
if (oTrue == true); // renders true
|
|
|
|
In other words, for `optional<>`, the following assertion does not hold:
|
|
|
|
assert((opt == false) == (!opt));
|
|
[endsect]
|