Boost C++ Libraries

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

Interface Design
PrevUpHomeNext

One part of the interface is for modifying and setting the initial state of the object. It has to be able to say that

  • we want to store a specific value of type T,
  • we want to store no value.

The default constructor stores no value. Other than that, we require that the assignment and construction from a T reflects the former, while assignment and construction of a special tag value none reflect the latter need.

optional<int> o1;        // contains no value
optional<int> o2 = 2;    // contains value 2
optional<int> o3 = none; // contains no value

o1 = 1;    // assign value 1
o2 = none; // assign a no-value
o3 = {};   // assign a no-value
Inspecting the State

Inspecting the state of an optional object requires two steps:

  • check if we have the value or not,
  • if so, read the stored value.

This 'procedure' is characteristic of inspecting pointers in C++, therefore the pointer-like syntax was chosen to represent this.

void inspect (optional<string> os)
{
  if (os) {               // contextual conversion to `bool`
    read_string(*os);     // `operator*` to access the stored value
    read_int(os->size()); // `operator->` as shortcut for accessing members
  }
}

Also, similarly to pointers, if you access the value when it is not there, you trigger undefined behavior. This library detects and reports it via BOOST_ASSERT(). This common property of pointers and optional<> has been formalized into a concept OptionalPointee.

However, there is also the counter-intuitive part. All pointers embed shallow-copy semantics: when you copy a pointer, the pointed-to object stays at the same location and you can access it via either of the pointers. This is unlike optional objects where the represented value is copied along.

[Caution] Caution

Optional objects are not pointers.

There is a similar difference in relational operations: they compare deeply for optional<>, while they are shallow for pointers.

[Note] Note

When you need a deep relational operations that work uniformly for optional<> and pointers in generic contexts, use functions equal_pointees() and less_pointees().


PrevUpHomeNext