Mutable Access
A matter of const
optional
provides – naturally – access to the value it stores. We have
multiple ways to do so, but they all lack one capability.
Let’s say, we store a std::vector<int>
in our optional
and we want to push a value in it.
This code won’t compile. The error message will look basically like this:
We have seen such an error before. The issue is, that the ->
operator returns a
pointer to a const T
– in this case a const std::vector<int>
. We then try to call push_back
on this object, which
is rejected, because push_back is not a const
member
function.
This means that, if we want to be able to write code as done above, we will need to provide mutable access to an optional’s value. So we need to provide non-const versions of
value()
- the
*
operator and - the
->
operator.
Adding the tests
Creating a suitable test is pretty straight forward:
catch’s SECTIONs come in
quite handy here. Each of the SECTION
s we introduced here are executed independently although they share the same
setup and assertion code.
Adding mutable access
The implementation is rather simple, too: we basically can copy the const
versions of the accessor member functions
and operators and remove the const
qualifiers from the signature.
This is enough to make the new test pass. It is not that nice though that we have to
repeat ourselfs that much. For the operators it is not that bad
after all, but for value()
it is just ridiculous. Luckily we can help ourselfs by introducing a little helper function.
Conclusion
With these changes our optional
can now finally be mutated via value()
, *
and ->
. This is great, as it allows
for many more use cases. Additionally it should not be on us – library implementers – to decide whether is should be
allowed for a used to change the value of an optional of not. With this solution, the user can make this decision on
it’s own simply but putting a const
on the respective optional
or not.