Namensräume
Varianten
Aktionen

std::lexicographical_compare_three_way

Von cppreference.com
< cpp‎ | algorithm
 
 
Algorithmenbibliothek
Beschränkte Algorithmen und Algorithmen für Bereiche (C++20)
Beschränkte Algorithmen, z.B. ranges::copy, ranges::sort, ...
Ausführungsrichtlinien (C++17)
Nicht-modifizierende Sequenzoperationen
Stapeloperationen
(C++17)
Suchoperationen
(C++11)                (C++11)(C++11)

Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Ordnungsändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Zusammenführungsoperationen (auf sortierten Bereichen)
Heapoperationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikographische Vergleichsoperationen
lexicographical_compare_three_way
(C++20)
Permutationsoperationen
C-Bibliothek
Numerische Operationen
Operationen auf uninitialisiertem Speicher
 
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 lexikographisch zwei Bereiche [first1last1) und [first2last2) mittels Drei-Wege-Vergleich und erzeugt ein Ergebnis vom stärksten anwendbaren Vergleichskategoriyp.

1) Gibt die Reihenfolge zwischen dem ersten nicht-äquivalenten Elementpaar gemäß comp in beiden Bereichen zurück, falls vorhanden, andernfalls (wenn ein Bereich äquivalent zum Präfix des anderen gemäß comp ist), gibt die Reihenfolge 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 Vergleichskategoriypien ist, ist das Programm schlecht geformt.

Inhalt

[bearbeiten] Parameter

first1, last1 - das Iteratorenpool, das den ersten Bereich der zu untersuchenden Elemente definiert
first2, last2 - das Iteratorenpool, das den zweiten Bereich der zu untersuchenden Elemente definiert
comp - ein Funktionsaufrufobjekt
Typanforderungen
-
InputIt1, InputIt2 müssen die Anforderungen an LegacyInputIterator erfüllen.

[bearbeiten] Rückgabewert

Der Wert eines oben angegebenen Vergleichskategoriyp.

[bearbeiten] 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().

[bearbeiten] 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;
}

[bearbeiten] 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"

[bearbeiten] Fehlerberichte

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

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
LWG 3410 C++20 überflüssige Vergleiche zwischen Iteratoren waren erforderlich eine solche Anforderung wurde entfernt

[bearbeiten] Siehe auch

gibt true zurück, wenn ein Bereich lexikographisch kleiner als ein anderer ist
(Funktionsvorlage) [editieren]
beschränkte Funktionsobjekte, die x <=> y implementieren
(Klasse) [edit]
gibt true zurück, wenn ein Bereich lexikographisch kleiner als ein anderer ist
(Algorithmus-Funktionsobjekt)[bearbeiten]