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.
std::optional<NonReturnable&> is ill-formed due to value_orSection: 22.5.4.6 [optional.ref.observe] Status: New Submitter: Jiang An Opened: 2025-07-25 Last modified: 2025-10-16
Priority: 1
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.
T& from valid contained types. Given only value_or is
problematic here, perhaps we can avoid providing it if T is not returnable.
[2025-10-16; Reflector poll]
Set priority to 1 after reflector poll.
Why not just add Constraints: and use decay_t<T>
for the return type, instead of "not always present" which is currently
only used for member types, not member functions.
Previous resolution [SUPERSEDED]:
This wording is relative to N5014.
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 […] }; }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
-9- Mandates:Xberemove_cv_t<T>.is_constructible_v<X, T&> && is_convertible_v<U, X>istrue. -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
Tis a non-array object type.
[2025-10-16; Jonathan provides new wording]
Proposed resolution:
This wording is relative to N5014.
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;-?- Constraints:
Tis a non-array object type.-8- Let
-9- Mandates:Xberemove_cv_t<T>.is_constructible_v<X, T&> && is_convertible_v<U, X>istrue. -10- Effects: Equivalent to:return has_value() ? *val : static_cast<X>(std::forward<U>(u));-?- Remarks: The return type is unspecified if
Tis an array type or a non-object type. [Note ?: This is to avoid the declaration being ill-formed. — end note]