When we can use uniform initialization to easily default construct a std::optional<T>
?
std::optional<T> foo() {
if (on_error)
return {};
// ...
}
Is there any drawback to the above which std::nullopt
solves?
No.
This is a perfectly valid way to default-construct an optional
.
Even for assignment, you can copy-assign a default-constructed optional
with = {}
instead of using std::nullopt
:
cppreference actually says as much:
The constraints on
nullopt_t
's constructors exist to support bothop = {};
andop = nullopt;
as the syntax for disengaging an optional object.
… as does the original proposal for the feature:
Note that it is not the only way to disengage an optional object. You can also use:
op = std::nullopt;
You might ask yourself why, then, std::nullopt
exists at all. The proposal addresses this, too:
it introduces redundancy into the interface
[similar example]
On the other hand, there are usages where the usage of nullopt cannot be replaced with any other convenient notation:
void run(complex<double> v); void run(optional<string> v); run(nullopt); // pick the second overload run({}); // ambiguous if (opt1 == nullopt) ... // fine if (opt2 == {}) ... // illegal bool is_engaged( optional<int> o) { return bool(o); // ok, but unclear return o != nullopt; // familiar }
While some situations would work with {} syntax, using nullopt makes the programmer's intention more clear. Compare these:
optional<vector<int>> get1() { return {}; } optional<vector<int>> get2() { return nullopt; } optional<vector<int>> get3() { return optional<vector<int>>{}; }
In short, std::nullopt
can be useful, but in your case it simply comes down to style.
Is there any drawback to the above which
std::nullopt
solves?
Yes.
In some contexts you may want to conditionally return a disengaged optional object (empty, if you’d like) and the {}
initialization syntax cannot be non-ambiguously used to deduce the std::nullopt_t
type. E.g., as is covered in Return Optional value with ?: operator, when returning an empty or non-empty optional through a ternary operator expression:
return it != map.end() ? std::make_optional(it->second) : std::nullopt;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With