Namensräume
Varianten

std::three_way_comparable, std::three_way_comparable_with

Aus cppreference.com
<tbody> </tbody>
definiert in Header <compare>
template<class T, class Cat = std::partial_ordering> concept three_way_comparable = __WeaklyEqualityComparableWith<T, T> && __PartiallyOrderedWith<T, T> && requires(const std::remove_reference_t<T>& a, const std::remove_reference_t<T>& b) { { a <=> b } -> __ComparesAs<Cat>; };
(1)
template<class T, class U, class Cat = std::partial_ordering> concept three_way_comparable_with = std::three_way_comparable<T, Cat> && std::three_way_comparable<U, Cat> && std::common_reference_with< const std::remove_reference_t<T>&, const std::remove_reference_t<U>&> && std::three_way_comparable< std::common_reference_t< const std::remove_reference_t<T>&, const std::remove_reference_t<U>&>, Cat> && __WeaklyEqualityComparableWith<T, U> && __PartiallyOrderedWith<T, U> && requires(const std::remove_reference_t<T>& t, const std::remove_reference_t<U>& u) { { t <=> u } -> __ComparesAs<Cat>; { u <=> t } -> __ComparesAs<Cat>; };
(2)
template<class T, class Cat> concept __ComparesAs = // exposition only std::same_as<std::common_comparison_category_t<T, Cat>, Cat>;
(3)
1) Das Konzept std::three_way_comparable spezifiziert, daß der 3-Wegevergleichsoperator <=> angewandt auf T ein Ergebnis erzeugt, daß konsistent mit der durch Cat implizierten Vergleichskategorie ist.
2) Das Konzept std::three_way_comparable_with spezifiert, daß der 3-Wegevergleichsoperator <=> auf, mit möglicherweise verschiedenen Typen, T und U ein Ergebnis erzeugt, daß konsistent mit der durch Cat implizierten Vergleichskategorie ist. Das Vergleichen von gemischten Operanden erzielt das gleiche Ergebnis wie der Vergleich der Operanden nach dem Konvertieren in den gemeinsamen Type.

In beiden Definitionen __WeaklyEqualityComparableWith und __PartiallyOrderedWith sind reine Darstellungskonzepte, die auch von equality_comparable and totally_ordered benutzt werden.

Anforderungen an die Semantik

Diese Konzepte sind nur vorhanden, falls sie erfüllt sind und alle Konzepte, die sie einschließen ebenfalls vorhanden sind.

1) std::three_way_comparable<T, Cat> für T und Cat ist nur vorhanden, falls für gegebene lokalisierbare Werte (lvalue) a und b vom Type const std::remove_reference_t<T> das Folgende gilt:
  • (a <=> b == 0) == bool(a == b)
  • (a <=> b != 0) == bool(a != b)
  • ((a <=> b) <=> 0) und (0 <=> (b <=> a)) sind gleich
  • bool(a > b) == bool(b < a)
  • bool(a >= b) == !bool(a < b)
  • bool(a <= b) == !bool(b < a)
  • (a <=> b < 0) == bool(a < b)
  • (a <=> b > 0) == bool(a > b)
  • (a <=> b <= 0) == bool(a <= b)
  • (a <=> b >= 0) == bool(a >= b)
  • falls Cat convertierbar zu std::strong_ordering ist, so erfüllt T die Anforderungen von totally_ordered
2) std::three_way_comparable_with<T, U, Cat> für T, U und Cat ist nur vorhanden, falls für gegebenes
  • t, ein lokalisierbarer Wert vom Type const std::remove_reference_t<T>,
  • u, ein lokalisierbarer Wert vom Type const std::remove_reference_t<U>

und mit C gleich std::common_reference_t<const std::remove_reference_t<T>&, const std::remove_reference_t<U>&> das Folgende gilt:

  • t <=> u and u <=> t haben den gleichen Bereich
  • ((t <=> u) <=> 0) and (0 <=> (u <=> t)) sind gleich
  • (t <=> u == 0) == bool(t == u)
  • (t <=> u != 0) == bool(t != u)
  • Cat(t <=> u) == Cat(C(t) <=> C(u))
  • (t <=> u < 0) == bool(t < u)
  • (t <=> u > 0) == bool(t > u)
  • (t <=> u <= 0) == bool(t <= u)
  • (t <=> u >= 0) == bool(t >= u)
  • falls Cat convertierbar zu std::strong_ordering ist, so erfüllen T und U die Anforderungen von std::totally_ordered_with<T, U>.

Bewahrung der Gleicheit

Ein Ausdruck bewahrt die Gleichheit, falls es für gleiche Eingaben gleiche Ausgaben erzeugt.

  • Die Eingaben eines Ausdrucks bestehen aus den Operanden.
  • Die Ausgaben eines Ausdrucks bestehen aus den Ergebnissen und allen Operanden, die durch den Ausdruck verändert werden.

In der Spezifikation der Standardkonzepte sind Operanden definiert als der größtmögliche Unterausdruck, der * eine id-expression und

beinhaltet.

Die CV-Qualifikation und Wertkategory für jeden Operanden wird festgelegt unter der Anname, daß jeder Templateparameter für eine Type einen cv-unqualifizierter, vollständiger, nicht-array Objekttype ist.

Jeder Ausdruck, der die Gleichheit bewahren muß, muß weiterhin stabil sein, d.h. zweifache Evaluation eines solchen Ausdrucks mit den selben Eingabeobjekten muß die gleiche Ausgabe haben, wenn dazwischen keine expliziten Veränderungen an diesen Eingabeobjekten vorgenommen worden ist.

Solange nicht anders beschrieben, muß jeder Ausdruck, der in einem requires-Ausdruck benutzt wird, die Gleichheit bewahren und stabil sein und die Evaluation des Ausdruckes darf nur die nicht-konstanten Operanden verändern. Konstante Operanden dürfen nicht verändert werden

Implizite Ausdruckvariationen

Für einen requires-expression, der einen nichtverändernden Ausdruck für einen konstanten, lokalisierbaren Operand (lvalue) benutzt, sind implizite auch zusätzliche Variationen dieses Ausdruck erforderlich, die einen nichtkonstanten, lokalisierbaren Operanden oder einen möglicherweise konstanten lesbaren (rvalue) Operanden unterstützen, wenn nicht eine Ausdruckvariation mit abweichender Semantik explizit erforderlich ist. Diese impliziten Ausdrucksvariationen müssen die selben Anforderungen an die Semantik erfüllen wie der explizit deklarierte Ausdruck. Der Ausmaß, in der eine Implementierung die Syntax dieser Variationen überprüft, ist nicht definiert.

Referenzen

spezifiert, daß Operator == eine Äquivalenzbeziehung ist
(Konzept) [edit]
spezifiert, daß der Vergleichsoperator auf dem Type eine totale Ordnung erzeugt
(Konzept) [edit]