https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115059
Bug ID: 115059 Summary: Constraints/Mandates on the comparison operators of std::optional and std::variant are overly strict Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: de34 at live dot cn Target Milestone: --- The following example should compile in C++23/26 (or some other modes where explicit object parameters are available) due to CWG DR 2813 (https://cplusplus.github.io/CWG/issues/2813.html), given that [optional.relops] and [variant.relops] only require the result to be convertible to bool. ``` #include <optional> #include <variant> class PinnedBoolean { private: bool val_; PinnedBoolean(const PinnedBoolean&) = delete; PinnedBoolean& operator=(const PinnedBoolean&) = delete; public: constexpr explicit PinnedBoolean(bool b) noexcept : val_{b} {} constexpr operator bool(this PinnedBoolean x) noexcept { return x.val_; } }; static_assert(PinnedBoolean{true}); struct X { friend constexpr PinnedBoolean operator==(X, X) noexcept { return PinnedBoolean{true}; } friend constexpr PinnedBoolean operator!=(X, X) noexcept { return PinnedBoolean{false}; } }; static_assert(std::optional<X>{} == std::optional<X>{}); static_assert(std::variant<X>{} == std::variant<X>{}); ``` However, libc++ is currently applying stricter requirements (https://godbolt.org/z/Mc3bse5h7). Since CWG2813, both __boolean_testable and is_convertible_v are stricter than the plain "convertible to", because the implicit conversion from the result type to bool can be only well-formed for prvalues but not xvalues.