Reputation: 301
std::optional
can use the syntax to access its value similar to a normal pointer, like .
std::optional<string> some_str;
if (some_str)
(*some_str).c_str();
but it also has two functions, has_value()
and value()
to provide access to its value and to check if the value exists.
std::optional<string> some_str;
if (some_str.has_value())
some_str.value().c_str();
I am wondering what is the difference between these two
Is it for?
1. more verbose
2. performance?
3. better logging and debugging? value()
will throw exception.
Upvotes: 13
Views: 12520
Reputation: 302852
There are two separate things here.
First, explicit operator bool() const
vs bool has_value() const
. These are exactly synonyms. They mean the exact same thing. Use whichever one you prefer.
Second, T& value()
vs T& operator*()
. This is the same as vector::at
vs. vector::operator[]
. The former has no preconditions - it checks and throws - the latter has preconditions - it is undefined behavior if the optional is disengaged.
Upvotes: 18
Reputation: 62563
std::optional
(no experimental, C++17 is upon us) defines two different interfaces to access it's optional member: the checked access (std::optional::value
) and the unchecked access (operator*
).
Using checked access has two potential drawbacks - first, it slows execution down because branch is executed, and second, in case of value not being there it will throw an exception, which could be undesirable in terms of control flow. While the second issue can be alleviated via explicit check for value present (std::optional::has_value
) before calling value, the run-time performance cost could still be there.
An unchecked access doesn't have performance cost associated to that, but can only be safely used if you know that the value is there by some other means (i.e. you checked has_value
before). Otherwise, behavior of the program is undefined, and we do not want that.
From the above, it should be obvious that the second snippet you have shown is excessive:
if (some_str.has_value())
some_str.value().c_str();
Does the check for value presence twice (at least semantically, compilers are likely to be able to optimize the second check away). Still, the clearer code would be
if (some_str.has_value())
some_str->c_str();
Upvotes: 7