This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 3424. `optional::value_or` should never return a cv-qualified type

Section: 22.5.3.6 [optional.observe] Status: New Submitter: Casey Carter Opened: 2020-04-02 Last modified: 2020-09-06

Priority: 3

View other active issues in [optional.observe].

View all other issues in [optional.observe].

View all issues with New status.

Discussion:

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.

[2020-04-18 Issue Prioritization]

Priority to 3 after reflector discussion.

Proposed resolution:

This wording is relative to N4861.

1. Modify 22.5.3 [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&&) &&;
   >     […]

2. Modify 22.5.3.6 [optional.observe] as indicated:

   > [Drafting note: The two removals of the `&&` in `is_convertible_v<U&&, T>` below is just a drive-by simplification]

   >     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));