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_type
defined 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: true
when the object contains a value, orfalse
otherwise.
-
constexpr value_type const &
value
() const¶ Get a const reference to the contained value.
Throw: an exception of class bad_optional_access
when the object is empty.
-
value_type &
value
()¶ Get a reference to the contained value.
Throw: an exception of class bad_optional_access
when the object is empty.
-
constexpr value_type
value_or
(U &&v) const &¶ Get the contained value, or a static convertion of
v
to the typeT
(when the object is empty).
-
value_type
value_or
(U &&v) &&¶ Get the contained value, or a static convertion of
v
to 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:
x
is empty whiley
is 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.