...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
Suppose we want to implement a lazy load optimization.
This is because we do not want to perform an expensive initialization of
our Resource
until (if at
all) it is really used. We can do it this way:
class Widget { mutable boost::optional<const Resource> resource_; public: Widget() {} const Resource& getResource() const // not thread-safe { if (resource_ == boost::none) resource_.emplace("resource", "arguments"); return *resource_; } };
optional
's default constructor
creates an uninitialized optional. No call to Resource
's
default constructor is attempted. Resource
doesn't have to be DefaultConstructible
. In function
getResource
we first check
if resource_
is initialized.
This time we do not use the contextual conversion to bool
,
but a comparison with boost::none
.
These two ways are equivalent. Function emplace
initializes the optional in-place by perfect-forwarding the arguments to
the constructor of Resource
.
No copy- or move-construction is involved here. Resource
doesn't even have to be MoveConstructible
.
Note | |
---|---|
Function |