std::three_way_comparable, std::three_way_comparable_with
| 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) | |
std::three_way_comparable spezifiziert, daß der 3-Wegevergleichsoperator <=> angewandt auf T ein Ergebnis erzeugt, daß konsistent mit der durch Cat implizierten Vergleichskategorie ist.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.
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 gleichbool(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
Catconvertierbar zu std::strong_ordering ist, so erfülltTdie Anforderungen vontotally_ordered
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 Typeconst std::remove_reference_t<T>,u, ein lokalisierbarer Wert vom Typeconst 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 <=> uandu <=> thaben 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
Catconvertierbar zu std::strong_ordering ist, so erfüllenTundUdie Anforderungen vonstd::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
- einen Aufruf von std::move, std::forward und std::declval.
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) | |
| spezifiert, daß der Vergleichsoperator auf dem Type eine totale Ordnung erzeugt (Konzept) | |