Here's the definition of value_or()
from the C++17 standard:
template <class U> constexpr T value_or(U&& v) const&;
Effects: Equivalent to:
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
Remarks: If
is_copy_constructible_v<T> && is_convertible_v<U&&, T>
isfalse
, the program is ill-formed.
(the rvalue overload is similar)
The effect of value_or
is described as equivalent to return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
operator bool
is noexcept
. operator*
is not noexcept
(even though it doesn't throw, probably because it can still fail with UB if used when the optional does not contain a value). However, we are guaranteed to never try to return the contained value unless we have one.
So couldn't value_or
be declared noexcept
given is_nothrow_copy_constructible<T> && noexcept(static_cast<T>(std::forward<U>(v)))
?