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.

4304. std::optional<NonReturnable&> is ill-formed due to value_or

Section: 22.5.4.6 [optional.ref.observe] Status: New Submitter: Jiang An Opened: 2025-07-25 Last modified: 2025-07-27

Priority: Not Prioritized

View all issues with New status.

Discussion:

Currently, if T is an array type or a function type, instantiation of std::optional<T&> is still ill-formed, because the return type of its value_or member function is specified as remove_cv_t<T>, which is invalid as a return type.

However, we don't exclude such T& from valid contained types. Given only value_or is problematic here, perhaps we can avoid providing it if T is not returnable.

Proposed resolution:

This wording is relative to this CD preview draft.

  1. Modify 22.5.4.1 [optional.optional.ref.general], header <iterator> synopsis, as indicated:

    namespace std {
      template<class T>
      class optional<T&> {
        […]
        constexpr T& value() const; // freestanding-deleted
        template<class U = remove_cv_t<T>>
          constexpr remove_cv_t<T> value_or(U&& u) const; // not always present
        […]
      };
    }
    
  2. Modify 22.5.4.6 [optional.ref.observe] as indicated:

    template<class U = remove_cv_t<T>> constexpr remove_cv_t<T> value_or(U&& u) const;
    

    -8- Let X be remove_cv_t<T>.

    -9- Mandates: 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));
    

    -?- Remarks: This function template is present if and only if T is a non-array object type.