Boost C++ Libraries of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards


Relational operators

Type optional<T> is EqualityComparable whenever T is EqualityComparable. Two optional objects containing a value compare in the same way as their contained values. The uninitialized state of optional<T> is treated as a distinct value, equal to itself, and unequal to any value of type T:

boost::optional<int> oN = boost::none;
boost::optional<int> o0 = 0;
boost::optional<int> o1 = 1;

assert(oN != o0);
assert(o1 != oN);
assert(o0 != o1);
assert(oN == oN);
assert(o0 == o0);

The converting constructor from T as well as from boost::none implies the existence and semantics of the mixed comparison between T and optional<T> as well as between none_t and optionl<T>:

assert(oN != 0);
assert(o1 != boost::none);
assert(o0 != 1);
assert(oN == boost::none);
assert(o0 == 0);

This mixed comparison has a practical interpretation, which is occasionally useful:

boost::optional<int> choice = ask_user();
if (choice == 2)

In the above example, the meaning of the comparison is 'user chose number 2'. If user chose nothing, he didn't choose number 2.

In case where optional<T> is compared to none, it is not required that T be EqualityComparable.

In a similar manner, type optional<T> is LessThanComparable whenever T is LessThanComparable. The optional object containing no value is compared less than any value of T. To illustrate this, if the default ordering of size_t is {0, 1, 2, ...}, the default ordering of optional<size_t> is {boost::none, 0, 1, 2, ...}. This order does not have a practical interpretation. The goal is to have any semantically correct default ordering in order for optional<T> to be usable in ordered associative containers (wherever T is usable).

Mixed relational operators are the only case where the contained value of an optional object can be inspected without the usage of value accessing function (operator*, value, value_or).