Created on 2020-04-02.00:00:00 last changed 22 months ago
Proposed resolution:
This wording is relative to N4928.
Modify [optional.optional.general] as indicated:
[…] template<class U> constexpr remove_cv_t<T> value_or(U&&) const&; template<class U> constexpr remove_cv_t<T> value_or(U&&) &&; […]
Modify [optional.observe] as indicated:
[Drafting note: The two removals of the && in is_convertible_v<U&&, T> below is a simplification to restore consistency with the wording for expected::value_or.]
template<class U> constexpr remove_cv_t<T> value_or(U&& v) const &;-?- Let R be remove_cv_t<T>.
-15- Mandates:is_copy_constructible_v<T>is_convertible_v<const T&, R> && is_convertible_v<U&&,TR> is true. -16- Effects: Equivalent to:return bool(*this) ? **this : static_cast<TR>(std::forward<U>(v));template<class U> constexpr remove_cv_t<T> value_or(U&& v) &&;-?- Let R be remove_cv_t<T>.
-17- Mandates:is_move_constructible_v<T>is_convertible_v<T, R> && is_convertible_v<U&&,TR> is true. -18- Effects: Equivalent to:return bool(*this) ? std::move(**this) : static_cast<TR>(std::forward<U>(v));
Modify [expected.object.general] as indicated:
[…] template<class U> constexpr remove_cv_t<T> value_or(U&&) const &; template<class U> constexpr remove_cv_t<T> value_or(U&&) &&; […]
Modify [expected.object.obs] as indicated:
template<class U> constexpr remove_cv_t<T> value_or(U&& v) const &;-?- Let R be remove_cv_t<T>.
-16- Mandates:is_copy_constructible_v<T>is_convertible_v<const T&, R> && is_convertible_v<U,TR> is true. -17- Returns: has_value() ? **this : static_cast<TR>(std::forward<U>(v)).template<class U> constexpr remove_cv_t<T> value_or(U&& v) &&;-?- Let R be remove_cv_t<T>.
-18- Mandates:is_move_constructible_v<T>is_convertible_v<T, R> && is_convertible_v<U,TR> is true. -19- Returns: has_value() ? std::move(**this) : static_cast<TR>(std::forward<U>(v)).
[ 2023-02-09 Casey improves wording and expands to cover expected::value_or ]
Since expected was modeled on optional, it has the same issue.
[ 2020-04-18 Issue Prioritization ]
Priority to 3 after reflector discussion.
Previous resolution [SUPERSEDED]:
This wording is relative to N4861.
Modify [optional.optional] as indicated:
[…] template<class U> constexpr remove_cv_t<T> value_or(U&&) const&; template<class U> constexpr remove_cv_t<T> value_or(U&&) &&; […]Modify [optional.observe] as indicated:
template<class U> constexpr remove_cv_t<T> value_or(U&& v) const&;-?- Let R be remove_cv_t<T>.
-17- Mandates:is_copy_constructible_v<T>is_convertible_v<const T&, R> && is_convertible_v<U&&, T> is true. -18- Effects: Equivalent to:return bool(*this) ? **this : static_cast<TR>(std::forward<U>(v));template<class U> constexpr remove_cv_t<T> value_or(U&& v) &&;-?- Let R be remove_cv_t<T>.
-19- Mandates:is_move_constructible_v<T>is_convertible_v<T, R> && is_convertible_v<U&&, T> is true. -20- Effects: Equivalent to:return bool(*this) ? std::move(**this) : static_cast<TR>(std::forward<U>(v));
The optional<T>::value_or overloads are specified to return T. This seems silly when T is const or volatile qualified — return types should never be cv-qualified. (In the volatile case, it is even deprecated since merging P1152R4 "Deprecating volatile" into the working draft.) We should strip cv-qualifiers from these return types.
History | |||
---|---|---|---|
Date | User | Action | Args |
2023-02-10 09:41:36 | admin | set | messages: + msg13330 |
2020-04-18 12:19:25 | admin | set | messages: + msg11223 |
2020-04-05 16:33:53 | admin | set | messages: + msg11198 |
2020-04-02 00:00:00 | admin | create |