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.
expected
may be ill-formedSection: 22.8.6.8 [expected.object.eq], 22.8.7.8 [expected.void.eq] Status: New Submitter: Hewill Kang Opened: 2025-09-06 Last modified: 2025-09-15
Priority: Not Prioritized
View all issues with New status.
Discussion:
These comparison functions all explicitly static_cast
the result of the underlying comparison to
bool
. However, the Constraints only require the implicit conversion, not the explicit one
(i.e., "convertible to bool
" rather than "models boolean-testable
").
#include <expected>
struct E1 {};
struct E2 {};
struct Bool {
operator bool() const;
explicit operator bool() = delete;
};
Bool operator==(E1, E2);
int main() {
std::unexpected e1{E1{}};
std::unexpected e2{E2{}};
return std::expected<int, E1>{e1} == e2; // fire
}
It is reasonable to specify return consistency with actual Constraints.
Proposed resolution:
This wording is relative to N5014.
Modify 22.8.6.8 [expected.object.eq] as indicated:
template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);-3- Constraints:
[Note 1:T2
is not a specialization ofexpected
. The expression*x == v
is well-formed and its result is convertible tobool
.T
need not be Cpp17EqualityComparable. — end note] -4- Returns: Ifx.has_value()
istrue
,; otherwise
&& static_cast<bool>(*x == v)false
.template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);-5- Constraints: The expression
-6- Returns: Ifx.error() == e.error()
is well-formed and its result is convertible tobool
.!x.has_value()
istrue
,; otherwise
&& static_cast<bool>(x.error() == e.error())false
.
Modify 22.8.7.8 [expected.void.eq] as indicated:
template<class T2, class E2> requires is_void_v<T2> friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);-1- Constraints: The expression
-2- Returns: Ifx.error() == y.error()
is well-formed and its result is convertible tobool
.x.has_value()
does not equaly.has_value()
,false
; otherwise ifx.has_value()
istrue
,true
; otherwise.
|| static_cast<bool>(x.error() == y.error())template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);-3- Constraints: The expression
-4- Returns: Ifx.error() == e.error()
is well-formed and its result is convertible tobool
.!x.has_value()
istrue
,; otherwise
&& static_cast<bool>(x.error() == e.error())false
.