Created on 2025-09-06.00:00:00 last changed 2 days ago
Proposed resolution:
This wording is relative to N5014.
Modify [optional.observe] as indicated:
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;-15- Mandates:
-16- Effects: Equivalent to:is_copy_constructible_v<T> && is_convertible_v<U&&, T>
is `true`.return has_value() ? **this : static_cast<T>(std::forward<U>(v));if (has_value()) return **this; return std::forward<U>(v);template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;-17- Mandates:
-18- Effects: Equivalent to:is_move_constructible_v<T> && is_convertible_v<U&&, T>
is `true`.return has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(v));if (has_value()) return std::move(**this); return std::forward<U>(v);
Modify [optional.ref.observe] as indicated:
template<class U = remove_cv_t<T>> constexpr remove_cv_t<T> value_or(U&& u) const;-8- Let
-9- Mandates:X
beremove_cv_t<T>
.is_constructible_v<X, T&> && is_convertible_v<U, X>
is `true`. -10- Effects: Equivalent to:return has_value() ? *val : static_cast<X>(std::forward<U>(u));if (has_value()) return *val; return std::forward<U>(u);
Modify [expected.object.obs] as indicated:
template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;-18- Mandates:
is_copy_constructible_v<T>
is `true` andis_convertible_v<U, T>
is `true`.-19- Returns:-?- Effects: Equivalent to:has_value() ? **this : static_cast<T>(std::forward<U>(v))
.if (has_value()) return **this; return std::forward<U>(v);template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) &&;-20- Mandates:
is_move_constructible_v<T>
is `true` andis_convertible_v<U, T>
is `true`.-21- Returns:-?- Effects: Equivalent to:has_value() ? std::move(**this) : static_cast<T>(std::forward<U>(v))
.if (has_value()) return std::move(**this); return std::forward<U>(v);
optional<T>::value_or(U&&)
requires is_convertible_v<U&&, T>
to ensure that `T` can be convert from `U` when `optional` has no value.
struct S {
operator int() const;
explicit operator int() = delete;
};
int main() {
std::optional<int>{}.value_or(S{}); // fire
}
It is reasonable to create objects that stick to Mandates. The same goes for `expected::value_or`.
Daniel: This issue has considerable overlap with LWG 4281.History | |||
---|---|---|---|
Date | User | Action | Args |
2025-10-10 15:07:03 | admin | set | messages: + msg15134 |
2025-09-06 00:00:00 | admin | create |