[libcxx-commits] [libcxx] [libc++] P2944R3: Constrained comparisions - `optional` (PR #144249)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 16 08:57:18 PDT 2025


================
@@ -982,72 +983,133 @@ public:
 template <class _Tp>
 optional(_Tp) -> optional<_Tp>;
 
-// Comparisons between optionals
+// [optional.relops] Relational operators
+
+#    if _LIBCPP_STD_VER >= 26
+template < class _Tp, class _Up>
+#    else
 template <
     class _Tp,
     class _Up,
     enable_if_t<is_convertible_v<decltype(std::declval<const _Tp&>() == std::declval<const _Up&>()), bool>, int> = 0>
-_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y) {
+#    endif
+_LIBCPP_HIDE_FROM_ABI constexpr bool operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
+#    if _LIBCPP_STD_VER >= 26
+  requires requires {
+    { *__x == *__y } -> __core_convertible_to<bool>;
----------------
frederick-vs-ja wrote:

Here's an example. [Godbolt link](https://godbolt.org/z/a8fhj198f) (the 2nd example has the constraints for `operator==` commented out):
```C++
#include <optional>
#include <type_traits>

namespace my {
  struct foo {};
  template<class T, class U>
    requires (!std::is_same_v<std::remove_cv_t<T>, foo>)
          && (!std::is_same_v<std::remove_cv_t<U>, foo>)
  bool operator==(const T&, const U&) { return true; }
}

int main() {
  using ofoo = std::optional<my::foo>;
  (void)(ofoo{} == ofoo{});
  // C++20/23: should select the standard overload and be ill-formed
  // C++26: should select the user-provided overload
}
```

https://github.com/llvm/llvm-project/pull/144249


More information about the libcxx-commits mailing list