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



Basic usage
Renaming the indeterminate state
tribool input/output

Basic usage

The tribool class acts like the built-in bool type, but for 3-state boolean logic. The three states are true, false, and indeterminate, where the first two states are equivalent to those of the C++ bool type and the last state represents an unknown boolean value (that may be true or false, we don't know).

The tribool class supports conversion from bool values and literals along with its own indeterminate keyword:

tribool b(true);
b = false;
b = indeterminate;
tribool b2(b);

tribool supports conversions to bool for use in conditional statements. The conversion to bool will be true when the value of the tribool is always true, and false otherwise. Consequently, the following idiom may be used to determine which of the three states a tribool currently holds:

tribool b = some_operation();
if (b) {
  // b is true
else if (!b) {
  // b is false
else {
  // b is indeterminate

tribool supports the 3-state logic operators ! (negation), && (AND), and || (OR), with bool and tribool values. For instance:

tribool x = some_op();
tribool y = some_other_op();
if (x && y) {
  // both x and y are true
else if (!(x && y)) {
  // either x or y is false
else {
  // neither x nor y is false, but we don't know that both are true

  if (x || y) {
    // either x or y is true

Similarly, tribool supports 3-state equality comparisons via the operators == and !=. These operators differ from "normal" equality operators in C++ because they return a tribool, because potentially we might not know the result of a comparison (try to compare true and indeterminate). For instance:

tribool x(true);
tribool y(indeterminate);

assert(x == x); // okay, x == x returns true
assert(x == true); // okay, can compare tribools and bools

The indeterminate keyword (representing the indeterminate tribool value) doubles as a function to check if the value of a tribool is indeterminate, e.g.,

tribool x = try_to_do_something_tricky();
if (indeterminate(x)) {
  // value of x is indeterminate
else {
  // report success or failure of x

All the logical operators and methods of tribool are marked as constexpr in C++11. It means that tribool can be used in compile time expressions:

constexpr tribool x = (tribool(true) || tribool(indeterminate));
static_assert(x, "Must be true!");
[Note] Note
Some compilers may have troubles with evaluating tribool::operator safe_bool() at compile time.

Renaming the indeterminate state

Users may introduce additional keywords for the indeterminate value in addition to the implementation-supplied indeterminate using the BOOST_TRIBOOL_THIRD_STATE macro. For instance, the following macro instantiation (at the global scope) will introduce the keyword maybe as a synonym for indeterminate (also residing in the boost namespace):

tribool x = maybe;
if (maybe(x)) { /* ... */ }

tribool input/output

tribool objects may be read from and written to streams by including the boost/logic/tribool_io.hpp header in a manner very similar to bool values. When the boolalpha flag is not set on the input/output stream, the integral values 0, 1, and 2 correspond to tribool values false, true, and indeterminate, respectively. When boolalpha is set on the stream, arbitrary strings can be used to represent the three values, the default being "false", "true", and "indeterminate". For instance:

tribool x;
cin >> x; // Type "0", "1", or "2" to get false, true, or indeterminate
cout << boolalpha << x; // Produces "false", "true", or "indeterminate"

tribool input and output is sensitive to the stream's current locale. The strings associated with false and true values are contained in the standard std::numpunct facet, and the string naming the indeterminate type is contained in the indeterminate_name facet. To replace the name of the indeterminate state, you need to imbue your stream with a local containing a indeterminate_name facet, e.g.:

locale global;
locale test_locale(global, new indeterminate_name<char>("maybe"));
tribool x(maybe);
cout << boolalpha << x << endl; // Prints "maybe"

If you C++ standard library implementation does not support locales, tribool input/output will still work, but you will be unable to customize the strings printed/parsed when boolalpha is set.