Spec-Zone.ru › C++

std::equality_comparable, std::equality_comparable_with

Определено в заголовке <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 задает, что операторы сравнения == и != для (возможно смешанных) T и U операндов дают результаты, согласующиеся с равенством. Сравнение смешанных операндов дает результаты, эквивалентные сравнению операндов, преобразованных к общему типу.
3) Концепция __WeaklyEqualityComparableWith (только для иллюстрации) задает, что объект типа T и объект типа U могут быть сравнены на равенство друг с другом (в любом порядке) с использованием как ==, так и !=, и результаты сравнений согласованы.
4) Концепция __ComparisonCommonTypeWith (только для иллюстрации) задает, что два типа имеют общий тип, и константное lvalue или неконстантное rvalue(с 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> моделируется только если, учитывая объекты a и b типа T, bool(a == b) равно true тогда и только тогда, когда a и b равны. Вместе с требованием, что a == b является сохраняющим равенство, это подразумевает, что == является симметричным и транзитивным, и далее, что == является рефлексивным для всех объектов a, которые равны по крайней мере одному другому объекту.
2) std::equality_comparable_with<T, U> моделируется только если, пусть
  • t и t2 являются lvalues, обозначающими различные равные объекты типов const std::remove_reference_t<T> и std::remove_cvref_t<T> соответственно,
  • u и u2 являются lvalues, обозначающими различные равные объекты типов const std::remove_reference_t<U> и std::remove_cvref_t<U> соответственно,
  • C является std::common_reference_t<const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>,

следующее выражение истинно:

  • bool(t == u) == bool(CONVERT_TO<C>(t2) == CONVERT_TO<C>(u2)).
3) __WeaklyEqualityComparableWith<T, U> моделируется только если, учитывая
  • t, lvalue типа const std::remove_reference_t<T> и
  • u, lvalue типа const std::remove_reference_t<U>,

следующие утверждения верны:

  • t == u, u == t, t != u, u != 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)

Пусть

  • C является std::common_reference_t<const T&, const U&>,
  • t1 и t2 являются сохраняющими равенство выражениями, являющимися lvalues типа std::remove_cvref_t<T>,
  • u1 и u2 являются сохраняющими равенство выражениями, являющимися lvalues типа std::remove_cvref_t<U>,

следующие условия выполняются:

  • CONVERT_TO<C>(t1) равно CONVERT_TO<C>(t2) тогда и только тогда, когда t1 равно t2; и
  • CONVERT_TO<C>(u1) равно CONVERT_TO<C>(u2) тогда и только тогда, когда u1 равно u2.
(с C++23)

Сохранение равенства

Выражения, объявленные в выражениях requires концепций стандартной библиотеки, должны быть сохраняющими равенство (если не указано иное).

Неявные вариации выражений

Выражение requires, которое использует выражение, не изменяющее некоторые постоянные операнды lvalue, также требует неявных вариаций выражений.

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/concepts/equality_comparable

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API