optional<T&>
was removed from the C++ standardization track because its use is questionable: it behaves nearly identically to a non-owning T*
with slightly different (and confusingly different from optional<T>
and T*
) semantics.
optional<T&>
is basically a non-owning T*
wrapped up pretty, and somewhat strangely.
Now, optional<T>
is a different beast.
I have used optional<Iterator>
in my container-based find algorithms. Instead of returning end()
, I return the empty optional. This lets users determine without a comparison if they have failed to find the item, and lets code like:
if(linear_search_for( vec, item))
work, while the same algorithm also lets you get at both the item and the location of the item in the container if you actually need it.
Pointers to elements doesn't give you the location information you might want except with contiguous containers.
So here, I've created a nullable iterator that has the advantages of iterators (generically working with different types of containers) and pointers (can be tested for the null state).
The next use is actually returning a value. Suppose you have a function that calculates a rectangle.
Rect GetRect();
now, this is great. But what if the question can be meaningless? Well, one approach is to return an empty rect or other "flag" value.
Optional lets you communicate that it can return a rect, or nothing, and not use the empty rect for the "nothing" state. It makes the return value nullable.
int GetValue();
is a better example. An invalid value could use a flag state of the int -- say -1
-- but that forces every user of your function to look up and track the flag state, and not accidentally treat it as a normal state.
Instead, optional<int> GetValue()
makes it clear that it can fail, and what the failure state it. If it is populated, you know it is a real value, and not a flag value.
In both of these cases, returning a non-owning pointer is non-viable, because who owns the storage? Returning an owning pointer is expensive, because pointless heap allocations are pointless.
Optionals are nullable value types. When you want to manage resources locally, and you still want an empty state, they make it clear.
Another thing to look into is the expected
type being proposed. This is an optional, but when in the empty state contains a reason why it is empty.