Namespaces
Variants
Actions

std::equality_comparable, std::equality_comparable_with

From cppreference.com
< cpp‎ | concepts
Defined in header <concepts>
template<class T >
concept equality_comparable = __WeaklyEqualityComparableWith<T, T>;
(1) (since 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<
            conststd::remove_reference_t<T>&,
            conststd::remove_reference_t<U>&>>&&

    __WeaklyEqualityComparableWith<T, U>;
(2) (since C++20)
Helper concepts
template<class T, class U >

concept __WeaklyEqualityComparableWith =
    requires(conststd::remove_reference_t<T>& t,
             conststd::remove_reference_t<U>& u){
        { t == u }->boolean-testable;
        { t != u }->boolean-testable;
        { u == t }->boolean-testable;
        { u != t }->boolean-testable;

    };
(3) (exposition only*)
(4)
template<class T, class U >

concept __ComparisonCommonTypeWith =
    std::common_reference_with<
        conststd::remove_reference_t<T>&,

        conststd::remove_reference_t<U>&>;
(until C++23)
(exposition only*)
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>>;
(since C++23)
(exposition only*)
1) The concept std::equality_comparable specifies that the comparison operators == and != on T reflects equality: == yields true if and only if the operands are equal.
2) The concept 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.
3) The exposition-only concept __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.
4) The exposition-only concept __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:

(until C++23)
  • static_cast<const C&>(std::as_const(E)) if that is a valid expression,
  • static_cast<const C&>(std::move(E)) otherwise.
(since C++23)
1)std::equality_comparable<T> is modeled only if, given objects 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.
2)std::equality_comparable_with<T, U> is modeled only if, let

the following expression is true:

  • bool(t == u)==bool(CONVERT_TO<C>(t2)== CONVERT_TO<C>(u2)).
3)__WeaklyEqualityComparableWith<T, U> is modeled only if given

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).
4)__WeaklyEqualityComparableWith<T, U> is modeled only if:

The corresponding common_reference_with concept is modeled.

(until C++23)

Let

the following conditions hold:

  • CONVERT_TO<C>(t1) equals CONVERT_TO<C>(t2) if and only if t1 equals t2; and
  • CONVERT_TO<C>(u1) equals CONVERT_TO<C>(u2) if and only if u1 equals u2.
(since C++23)

[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]
  • C++20 standard (ISO/IEC 14882:2020):
  • 18.5.3 Concept equality_comparable [concept.equalitycomparable]
close