Enter the void
The Discovery of a new useful function
While introducing the swap function we found it handy to modify
the already existing private member function destructValue
in a ways which made it even more
useful:
This function now does a bit more than “just” destroying the value stored in the optional –
it also sets mHasValue
back to false. This means that it takes an optional with a value
and transforms it in an optional without a value.
This is actually a quite helpful operation to have. We can currently already do something like by assigning an empty optional to the optional we want to be empty.
This solution works but it is a bit cumbersome and also requires us to instantiate a whole second
option just to do the simple operation which destrcutValue
basically already implements.
If we consider constructing an optional with a value to set it’s value, we could also consider
the operation to remove said value from the optional to reset the optional. reset
seems to
be a reasonable name for such a function – this is also the
name chosen in the C++ standard.
Tests for reset
There are quite obviously two conditions which can occur when calling such a reset function:
- the optional either has a value
- or it hasn’t.
In both cases we’d expect that after calling reset()
the optional has no value anymore.
The Implementation
After having a closer look at our test cases an destrcutValue
we will quickly realize
that reset
does a bit more than destructValue
. destrcutValue
has a
narrow contract: it requires mStorage
to actually
contain a value of type T
. Otherwise calling ~T
on this memory location is undefined behavior.
If we’d just rename destructValue
to reset
our second test case wouldn’t work. Therefore we
need to add an additional check before calling destructValue
.
With this implementation our test cases will pass and we’ll never invoke undefined behavior.
Conclusion
Based on a previously enhanced private member function we now can effortlessly reset and optional
calling reset
. In a previous post we already talked
about pointer’s being also some kind of optional and used this analogy to motivate the introduction
of the pointer syntax to optional. At the time we only considered
raw pointer (like they have
already been present in C), but there are (since C++11) smart pointers in the C++ standard like
std::shared_ptr or
std::unique_ptr and (even earlier)
boost::shared_ptr.
All of these smart pointer implement a reset
function:
All of them (if no argument is supplied) reset the value of the pointer – set the pointer to
the NULL pointer and destroys the value (at least potentially). This gives us another reason
to have a function called reset
within our optional: to not only be consistent with
raw pointers but with smart pointers, too.