Optional (Nullable)¶
In the C++ Extensions for Library Fundamentals (N4480), a class
template optional is introduced, which represents objects that may possibly
contain a value. Such types are widely provided by modern programming languages
(e.g. Nullable in C#, Maybe in Haskell, Optional in Swift,
and Option in Rust), and have shown their important utility in practice.
This library “backports” the optional type to C++11 (within the namespace
clue).
Here is a simple example that illustrates the use of the optional class.
#include <cmath>
#include <clue/optional.hpp>
using namespace clue;
inline optional<double> safe_sqrt(double x) {
return x >= 0.0 ?
make_optional(std::sqrt(x)) :
optional<double>();
}
auto u = safe_sqrt(-1.0); // -> optional<double>()
(bool)u; // -> false
u.value(); // throws an exception
u.value_or(0.0); // -> 0.0
auto v = safe_sqrt(4.0); // -> optional<double>(2.0)
(bool)v; // -> true
v.value(); // -> 2.0
v.value_or(0.0); // -> 2.0
The standard documentation of the optional type is available here. Below is a brief
description of this type.
Types¶
The class template optional is declared as:
-
class
optional¶ Formal: template <typename T> class optional;
Parameters: T – The type of the (possibly) contained value. The class
optional<T>has a member typedefvalue_typedefined asT.
In addition, several helper types are provided:
-
class
in_place_t¶ A tag type to indicate in-place construction of an optional object. It has a predefined instance
in_place.
-
class
nullopt_t¶ A tag type to indicate an optional object with uninitialized state. It is a predefined instance
nullopt.
Constructors¶
An optional object can be constructd in different ways:
-
constexpr
optional()¶ Constructs an empty optional object, which does not contain a value.
-
constexpr
optional(const value_type &v)¶ Construct an optional object that contains (a copy of) the input value
v.
-
constexpr
optional(value_type &&v)¶ Construct an optional object that contains the input value
v(moved in).
-
constexpr
optional(in_place_t, Args&&... args)¶ Construct an optional object, with the contained value constructed inplace with the initializing arguments
args.
Modifiers¶
After an optional object is constructed, its value can be re-constructed
later using swap, emplace, or the assignment operator.
-
void
emplace(Args&&... args)¶ Re-construct the contained value using the provided arguments
args.
Observers¶
Note
This class provides operator-> to allow the access of the contained
vlaue in a pointer form, and operator* to allow the access in a
dereferenced form. One must use these operators when the optional object
actually contains a value, otherwise it is undefined behavior.
A safer (but slightly less efficient) way to access the contained value is
to use value or value_or member functions described below.
-
explicit constexpr
operator bool() const noexcept¶ Convert the object to a boolean value.
Returns: truewhen the object contains a value, orfalseotherwise.
-
constexpr value_type const &
value() const¶ Get a const reference to the contained value.
Throw: an exception of class bad_optional_accesswhen the object is empty.
-
value_type &
value()¶ Get a reference to the contained value.
Throw: an exception of class bad_optional_accesswhen the object is empty.
-
constexpr value_type
value_or(U &&v) const &¶ Get the contained value, or a static convertion of
vto the typeT(when the object is empty).
-
value_type
value_or(U &&v) &&¶ Get the contained value, or a static convertion of
vto the typeT(when the object is empty).
Non-member Functions¶
Comparison¶
Comparison operators ==, !=, <, >, <=, >= are provided to compare optional objects.
Two optional objects are considered as equal if they meet either of the following two conditions:
- they are both empty, or
- they both contain values, and the contained values are equal.
An optional object x are considered as lesss than another optional object
y, if either of the following conditions are met:
xis empty whileyis not.- they both contain values, and
x.value() < y.value().
Note
Comparison between an optional object and a value v of type T is
allowed. In such cases, v is treated as an optional object that contains
a value v, and then the rules above apply.