| Home | Libraries | People | FAQ | More

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