std::equality_comparable, std::equality_comparable_with
<concepts>
concept equality_comparable = __WeaklyEqualityComparableWith<T, T>;
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>&>> &&
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 ;
concept __ComparisonCommonTypeWith =
std::common_reference_with <
const std::remove_reference_t <T>&,
(exposition only*)
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 =
(exposition only*)
std::equality_comparable
specifies that the comparison operators ==
and !=
on T
reflects equality: ==
yields true if and only if the operands are equal.std::equality_comparable_with
specifies that the comparison operators ==
and !=
on (possibly mixed) T
and U
operands yield results consistent with equality. Comparing mixed operands yields results equivalent to comparing the operands converted to their common type.__WeaklyEqualityComparableWith
specifies that an object of type T
and an object of type U
can be compared for equality with each other (in either order) using both ==
and !=
, and the results of the comparisons are consistent. __ComparisonCommonTypeWith
specifies that two types share a common type, and a const lvalue or a non-const rvalue(since C++23) of either type is convertible to that common type.Contents
[edit] Semantic requirements
These concepts are modeled only if they are satisfied and all concepts they subsume are modeled.
In the following paragraphs, given an expression E
and a type C
, CONVERT_TO<C>(E) is defined as:
- static_cast<C>(std::as_const (E)).
- static_cast<const C&>(std::as_const (E)) if that is a valid expression,
- static_cast<const C&>(std::move(E)) otherwise.
a
and b
of type T
, bool(a == b) is true if and only if a
and b
are equal. Together with the requirement that a == b is equality-preserving, this implies that ==
is symmetric and transitive, and further that ==
is reflexive for all objects a
that are equal to at least one other object.-
t
andt2
be lvalues denoting distinct equal objects of types const std::remove_reference_t <T> and std::remove_cvref_t <T> respectively, -
u
andu2
be lvalues denoting distinct equal objects of types const std::remove_reference_t <U> and std::remove_cvref_t <U> respectively, -
C
be std::common_reference_t <const std::remove_reference_t <T>&, const std::remove_reference_t <U>&>,
the following expression is true:
- bool(t == u) == bool(CONVERT_TO<C>(t2) == CONVERT_TO<C>(u2)).
-
t
, an lvalue of type const std::remove_reference_t <T> and -
u
, an lvalue of type const std::remove_reference_t <U>,
the following are true:
- t == u, u == t, t != u, u != t have the same domain;
- bool(u == t) == bool(t == u);
- bool(t != u) == !bool(t == u); and
- bool(u != t) == bool(t != u).
The corresponding common_reference_with
concept is modeled.
Let
-
C
be std::common_reference_t <const T&, const U&>, -
t1
andt2
be equality-preserving expressions that are lvalues of type std::remove_cvref_t <T>, -
u1
andu2
be equality-preserving expressions that are lvalues of type std::remove_cvref_t <U>,
the following conditions hold:
- CONVERT_TO<C>(t1) equals CONVERT_TO<C>(t2) if and only if
t1
equalst2
; and - CONVERT_TO<C>(u1) equals CONVERT_TO<C>(u2) if and only if
u1
equalsu2
.
[edit] Equality preservation
Expressions declared in requires expressions of the standard library concepts are required to be equality-preserving (except where stated otherwise).
[edit] Implicit expression variations
A requires expression that uses an expression that is non-modifying for some constant lvalue operand also requires implicit expression variations.
[edit] References
- C++23 standard (ISO/IEC 14882:2024):
- 18.5.4 Concept
equality_comparable
[concept.equalitycomparable]
- 18.5.4 Concept
- C++20 standard (ISO/IEC 14882:2020):
- 18.5.3 Concept
equality_comparable
[concept.equalitycomparable]
- 18.5.3 Concept