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.
optional<T>
to T
may be ill-formedSection: 22.5.9 [optional.comp.with.t] Status: New Submitter: Hewill Kang Opened: 2025-09-06 Last modified: 2025-09-15
Priority: Not Prioritized
View all other issues in [optional.comp.with.t].
View all issues with New status.
Discussion:
When comparing an optional
with its value type, the current wording specifies that the result is the
ternary expression of x.has_value() ? *x == v : false
, where *x == v
returns a result that can be
implicitly converted to bool
.
bool
(which is common), the ternary operation
will be ill-formed due to ambiguity (demo):
#include <optional>
struct Bool {
Bool(bool);
operator bool() const;
};
struct S {
Bool operator==(S) const;
};
int main() {
return std::optional<S>{} == S{}; // fire
}
Proposed resolution:
This wording is relative to N5014.
Modify 22.5.9 [optional.comp.with.t] as indicated:
template<class T, class U> constexpr bool operator==(const optional<T>& x, const U& v);-1- Constraints:
[Note 1:U
is not a specialization ofoptional
. The expression*x == v
is well-formed and its result is convertible tobool
.T
need not be Cpp17EqualityComparable. — end note] -2- Effects: Equivalent to:return x.has_value() ? *x == v : false;
if (x.has_value()) return *x == v; return false;template<class T, class U> constexpr bool operator==(const T& v, const optional<U>& x);-3- Constraints:
-4- Effects: Equivalent to:T
is not a specialization ofoptional
. The expressionv == *x
is well-formed and its result is convertible tobool
.return x.has_value() ? v == *x : false;
if (x.has_value()) return v == *x; return false;template<class T, class U> constexpr bool operator!=(const optional<T>& x, const U& v);-5- Constraints:
-6- Effects: Equivalent to:U
is not a specialization ofoptional
. The expression*x != v
is well-formed and its result is convertible tobool
.return x.has_value() ? *x != v : true;
if (x.has_value()) return *x != v; return true;template<class T, class U> constexpr bool operator!=(const T& v, const optional<U>& x);-7- Constraints:
-8- Effects: Equivalent to:T
is not a specialization ofoptional
. The expressionv != *x
is well-formed and its result is convertible tobool
.return x.has_value() ? v != *x : true;
if (x.has_value()) return v != *x; return true;template<class T, class U> constexpr bool operator<(const optional<T>& x, const U& v);-9- Constraints:
-10- Effects: Equivalent to:U
is not a specialization ofoptional
. The expression*x < v
is well-formed and its result is convertible tobool
.return x.has_value() ? *x < v : true;
if (x.has_value()) return *x < v; return true;template<class T, class U> constexpr bool operator<(const T& v, const optional<U>& x);-11- Constraints:
-12- Effects: Equivalent to:T
is not a specialization ofoptional
. The expressionv < *x
is well-formed and its result is convertible tobool
.return x.has_value() ? v < *x : false;
if (x.has_value()) return v < *x; return false;template<class T, class U> constexpr bool operator>(const optional<T>& x, const U& v);-13- Constraints:
-14- Effects: Equivalent to:U
is not a specialization ofoptional
. The expression*x > v
is well-formed and its result is convertible tobool
.return x.has_value() ? *x > v : false;
if (x.has_value()) return *x > v; return false;template<class T, class U> constexpr bool operator>(const T& v, const optional<U>& x);-15- Constraints:
-16- Effects: Equivalent to:T
is not a specialization ofoptional
. The expressionv > *x
is well-formed and its result is convertible tobool
.return x.has_value() ? v > *x : true;
if (x.has_value()) return v > *x; return true;template<class T, class U> constexpr bool operator<=(const optional<T>& x, const U& v);-17- Constraints:
-18- Effects: Equivalent to:U
is not a specialization ofoptional
. The expression*x <= v
is well-formed and its result is convertible tobool
.return x.has_value() ? *x <= v : true;
if (x.has_value()) return *x <= v; return true;template<class T, class U> constexpr bool operator<=(const T& v, const optional<U>& x);-19- Constraints:
-20- Effects: Equivalent to:T
is not a specialization ofoptional
. The expressionv <= *x
is well-formed and its result is convertible tobool
.return x.has_value() ? v <= *x : false;
if (x.has_value()) return v <= *x; return false;template<class T, class U> constexpr bool operator>=(const optional<T>& x, const U& v);-21- Constraints:
-22- Effects: Equivalent to:U
is not a specialization ofoptional
. The expression*x >= v
is well-formed and its result is convertible tobool
.return x.has_value() ? *x >= v : false;
if (x.has_value()) return *x >= v; return false;template<class T, class U> constexpr bool operator>=(const T& v, const optional<U>& x);-23- Constraints:
-24- Effects: Equivalent to:T
is not a specialization ofoptional
. The expressionv >= *x
is well-formed and its result is convertible tobool
.return x.has_value() ? v >= *x : true;
if (x.has_value()) return v >= *x; return true;