@@ -1791,6 +1791,16 @@ class optional<T&> {
17911791 */
17921792 constexpr T& value () const ;
17931793
1794+ // LWG4304. std::optional<NonReturnable&> is ill-formed due to value_o
1795+ // Resolution:
1796+ // -?- Constraints: T is a non-array object type.
1797+ // -?- Remarks: The return type is unspecified if T is an array type or a
1798+ // non-object type. [Note ?: This is to avoid the declaration being
1799+ // ill-formed. — end note]
1800+ //
1801+ // Implementer Note: Using decay_t as a detail as it is remove_cv_t for
1802+ // non-array objects, and produces a valid type for arrays and functions,
1803+ // which are otherwise `required` out.
17941804 /* *
17951805 * @brief Returns the contained value if there is one, otherwise returns `u`.
17961806 *
@@ -1799,7 +1809,8 @@ class optional<T&> {
17991809 * @return std::remove_cv_t<T>
18001810 */
18011811 template <class U = std::remove_cv_t <T>>
1802- constexpr std::remove_cv_t <T> value_or (U&& u) const ;
1812+ requires (std::is_object_v<T> && !std::is_array_v<T>)
1813+ constexpr std::decay_t <T> value_or (U&& u) const ;
18031814
18041815 // \ref{optionalref.monadic}, monadic operations
18051816 /* *
@@ -1991,7 +2002,8 @@ constexpr T& optional<T&>::value() const {
19912002
19922003template <class T >
19932004template <class U >
1994- constexpr std::remove_cv_t <T> optional<T&>::value_or(U&& u) const {
2005+ requires (std::is_object_v<T> && !std::is_array_v<T>)
2006+ constexpr std::decay_t <T> optional<T&>::value_or(U&& u) const {
19952007 static_assert (std::is_constructible_v<std::remove_cv_t <T>, T&>, " T must be constructible from a T&" );
19962008 static_assert (std::is_convertible_v<U, std::remove_cv_t <T>>, " Must be able to convert u to T" );
19972009 return has_value () ? *value_ : static_cast <std::remove_cv_t <T>>(std::forward<U>(u));
0 commit comments