std::equality_comparable, std::equality_comparable_with

来自cppreference.com
<tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody>
在标头 <concepts> 定义
template< class T > concept equality_comparable = __WeaklyEqualityComparableWith<T, T>;
(1) (C++20 起)
template< class T, class U > concept equality_comparable_with = std::equality_comparable<T> && std::equality_comparable<U> && __ComparisonCommonTypeWith<T, U> && std::equality_comparable< std::common_reference_t< const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>> && __WeaklyEqualityComparableWith<T, U>;
(2) (C++20 起)
辅助概念
template< class T, class U > concept __WeaklyEqualityComparableWith = requires(const std::remove_reference_t<T>& t, const std::remove_reference_t<U>& u) { { t == u } -> boolean-testable; { t != u } -> boolean-testable; { u == t } -> boolean-testable; { u != t } -> boolean-testable; };
(3) (仅用于阐述*)
(4)
template< class T, class U > concept __ComparisonCommonTypeWith = std::common_reference_with< const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>;
(C++23 前)
(仅用于阐述*)
template< class T, class U, class C = std::common_reference_t<const T&, const U&> > concept _ComparisonCommonTypeWithImpl = std::same_as<std::common_reference_t<const T&, const U&>, std::common_reference_t<const U&, const T&>> && requires { requires std::convertible_to<const T&, const C&> || std::convertible_to<T, const C&>; requires std::convertible_to<const U&, const C&> || std::convertible_to<U, const C&>; }; template< class T, class U > concept __ComparisonCommonTypeWith = _ComparisonCommonTypeWithImpl<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
(C++23 起)
(仅用于阐述*)
1) 概念 std::equality_comparable 指定比较运算符 ==!=T 上反映相等性:== 当且仅当操作数相等才生成 true
2) 概念 std::equality_comparable_with 指定比较运算符 ==!= 在(可能混合的)TU 操作数上生成与相等一致的结果。对混合的操作数比较产生的结果等价于对转换到其公共类型的操作数进行比较。
3) 仅用于阐释的概念 __WeaklyEqualityComparableWith 指定 T 类型的对象和 U 类型的对象能用 ==!= 彼此比较相等性(以任一顺序),而比较结果一致。
4) 仅用于阐释的概念 __ComparisonCommonTypeWith 指定两个类型共享一个公共类型,且任一类型的 const 左值或非 const 右值(C++23 起)均可转换为该公共类型。

语义要求

这些概念仅若其所蕴含的概念均被实现才得到实现。

以下段落中,给定表达式 E 和类型 C,定义 CONVERT_TO<C>(E) 为:

  • static_cast<C>(std::as_const(E))
(C++23 前)
  • static_cast<const C&>(std::as_const(E)),若其为有效表达式,
  • 否则为 static_cast<const C&>(std::move(E))
(C++23 起)
1) std::equality_comparable<T> 仅若符合下列条件才得到实现。给定 T 类型对象 abbool(a == b) 当且仅当 ab 相等才为 true。这与 a == b 保持相等性的要求一同蕴含了,== 为对称且传递,而且 == 进而对所有至少等于一个其他对象的 a 自反。
2) std::equality_comparable_with<T, U> 仅若符合下列条件才得到实现,令
  • tt2 分别为指代 const std::remove_reference_t<T>std::remove_cvref_t<T> 类型的不同但相等对象的左值,
  • uu2 分别为指代 const std::remove_reference_t<U>std::remove_cvref_t<U> 类型的不同但相等对象的左值,
  • Cstd::common_reference_t<const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>

则下列表达式为 true

  • bool(t == u) == bool(CONVERT_TO<C>(t2) == CONVERT_TO<C>(u2))
3) __WeaklyEqualityComparableWith<T, U> 仅若符合下列条件才得到实现。给定
  • tconst std::remove_reference_t<T> 类型的左值,和
  • uconst std::remove_reference_t<U> 类型的左值,

下列为真:

  • t == uu == tt != uu != t 拥有相同定义域;
  • bool(u == t) == bool(t == u)
  • bool(t != u) == !bool(t == u);且
  • bool(u != t) == bool(t != u)
4) __WeaklyEqualityComparableWith<T, U> 仅若符合下列条件才得到实现:

相应的 common_reference_with 概念已得实现,

(C++23 前)

  • Cstd::common_reference_t<const T&, const U&>
  • t1t2保持相等性表达式且为 std::remove_cvref_t<T> 类型的左值,
  • u1u2保持相等性表达式且为 std::remove_cvref_t<U> 类型的左值,

满足以下各条件:

  • 当且仅当 t1 等于 t2CONVERT_TO<C>(t1) 等于 CONVERT_TO<C>(t2);且
  • 当且仅当 u1 等于 u2CONVERT_TO<C>(u1) 等于 CONVERT_TO<C>(u2)
(C++23 起)

相等性保持

标准库概念的 requires 表达式中声明的表达式都要求保持相等性(除非另外说明)。

隐式表达式变种

使用了不修改某常量左值操作数的表达式的 requires 表达式,也会要求其隐式的表达式变种

引用

  • C++23 标准(ISO/IEC 14882:2024):
  • 18.5.4 Concept equality_comparable [concept.equalitycomparable]
  • C++20 标准(ISO/IEC 14882:2020):
  • 18.5.3 Concept equality_comparable [concept.equalitycomparable]