Namespaces
Variants

std::lexicographical_compare_three_way

Von de.cppreference.net
 
 
Algorithmenbibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Vertauschungsoperationen
Transformationsoperationen
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und zugehörige Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum-/Maximumoperationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
Definiert in Header <algorithm>
template< class InputIt1, class InputIt2, class Cmp >
constexpr auto lexicographical_compare_three_way
    ( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
      Cmp comp ) -> decltype(comp(*first1, *first2));
(1) (seit C++20)
template< class InputIt1, class InputIt2 >
constexpr auto lexicographical_compare_three_way
    ( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2 );
(2) (seit C++20)

Vergleicht zwei Bereiche [first1, last1) und [first2, last2) mithilfe eines Dreivegvergleichs lexikografisch und liefert ein Ergebnis des stärksten anwendbaren Vergleichskategorietyps.

1) Gibt die Ordnung zwischen dem ersten nicht-äquivalenten Elementpaar gemäß comp in beiden Bereichen zurück, falls vorhanden, andernfalls (wenn ein Bereich äquivalent zum Präfix eines anderen gemäß comp ist) gibt die Ordnung zwischen der Länge beider Bereiche zurück.
2) Äquivalent zu return std::lexicographical_compare_three_way(
first1, last1, first2, last2, std::compare_three_way());

Wenn der Rückgabetyp nicht einer der drei Vergleichskategorietypen ist, ist das Programm fehlerhaft:

Parameter

first1, last1 - das Paar von Iteratoren, das den ersten Bereich von zu untersuchenden Elementen definiert
first2, last2 - das Paar von Iteratoren, das den zweiten Bereich von zu untersuchenden Elementen definiert
comp - ein Funktionsobjekt
Typanforderungen
-
InputIt1, InputIt2 muss die Anforderungen von LegacyInputIterator erfüllen.

Rückgabewert

Der Wert eines oben angegebenen Vergleichskategorietyps.

Komplexität

Gegeben N1 als std::distance(first1, last1) und N2 als std::distance(first2, last2):

1) Höchstens min(1,N2) Anwendungen von comp.
2) Höchstens min(N1,N2) Anwendungen von std::compare_three_way().

Mögliche Implementierung

template<class I1, class I2, class Cmp>
constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp)
    -> decltype(comp(*f1, *f2))
{
    using ret_t = decltype(comp(*f1, *f2));
    static_assert(std::disjunction_v<
                      std::is_same<ret_t, std::strong_ordering>,
                      std::is_same<ret_t, std::weak_ordering>,
                      std::is_same<ret_t, std::partial_ordering>>,
                  "The return type must be a comparison category type.");
    
    bool exhaust1 = (f1 == l1);
    bool exhaust2 = (f2 == l2);
    for (; !exhaust1 && !exhaust2; exhaust1 = (++f1 == l1), exhaust2 = (++f2 == l2))
        if (auto c = comp(*f1, *f2); c != 0)
            return c;
    
    return !exhaust1 ? std::strong_ordering::greater:
           !exhaust2 ? std::strong_ordering::less:
                       std::strong_ordering::equal;
}

Beispiel

#include <algorithm>
#include <cctype>
#include <compare>
#include <iomanip>
#include <iostream>
#include <string_view>
#include <utility>

using namespace std::literals;

void show_result(std::string_view s1, std::string_view s2, std::strong_ordering o)
{
    std::cout << std::quoted(s1) << " is ";
    std::is_lt(o) ? std::cout << "less than ":
    std::is_gt(o) ? std::cout << "greater than ":
                    std::cout << "equal to ";
    std::cout << std::quoted(s2) << '\n';
}

std::strong_ordering cmp_icase(unsigned char x, unsigned char y)
{
    return std::toupper(x) <=> std::toupper(y);
};
    
int main()
{
    for (const auto& [s1, s2] :
    {
        std::pair{"one"sv, "ONE"sv}, {"two"sv, "four"sv}, {"three"sv, "two"sv}
    })
    {
        const auto res = std::lexicographical_compare_three_way(
            s1.cbegin(), s1.cend(), s2.cbegin(), s2.cend(), cmp_icase);
        show_result(s1, s2, res);
    }
}

Ausgabe:

"one" is equal to "ONE"
"two" is greater than "four"
"three" is less than "two"

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 3410 C++20 überflüssige Vergleiche zwischen Iteratoren waren erforderlich diese Anforderung entfernt

Siehe auch

vergleicht zwei Bereiche lexikografisch
(Funktionsschablone & Algorithmus-Funktionsobjekt)
eingeschränktes Funktionsobjekt, das implementiert x <=> y
(Klasse)
vergleicht zwei Bereiche lexikografisch
(Algorithmus-Funktionsobjekt)