Namespaces
Variants

std::lexicographical_compare_three_way

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p. ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones modificadoras de secuencia
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenación y relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenación
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjuntos (en rangos ordenados)
Operaciones de mezcla (en rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Definido en el encabezado <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) (desde C++20)
template< class InputIt1, class InputIt2 >
constexpr auto lexicographical_compare_three_way
    ( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2 );
(2) (desde C++20)

Compara lexicográficamente dos rangos [first1, last1) y [first2, last2) usando comparación de tres vías y produce un resultado del tipo de categoría de comparación más fuerte aplicable.

1) Devuelve el orden entre el primer par de elementos no equivalentes según comp en ambos rangos si lo hay, en caso contrario (si un rango es equivalente al prefijo de otro según comp), devuelve el orden entre las longitudes de ambos rangos.
2) Equivalente a return std::lexicographical_compare_three_way(
first1, last1, first2, last2, std::compare_three_way());

Si el tipo de retorno no es uno de los tres tipos de categoría de comparación, el programa está mal formado:

Parámetros

first1, last1 - el par de iteradores que definen el primer rango de elementos a examinar
first2, last2 - el par de iteradores que definen el segundo rango de elementos a examinar
comp - un objeto función
Requisitos de tipo
-
InputIt1, InputIt2 debe cumplir los requisitos de LegacyInputIterator.

Valor de retorno

El valor de un tipo de categoría de comparación especificado arriba.

Complejidad

Dado N1 como std::distance(first1, last1) y N2 como std::distance(first2, last2):

1) Como máximo min(1,N2) aplicaciones de comp.
2) Como máximo min(N1,N2) aplicaciones de std::compare_three_way().

Posible implementación

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;
}

Ejemplo

#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);
    }
}

Salida:

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

Informes de defectos

Los siguientes informes de defectos que cambian el comportamiento se aplicaron retroactivamente a los estándares C++ previamente publicados.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 3410 C++20 se requerían comparaciones superfluas entre iteradores dicho requerimiento eliminado

Véase también

compara dos rangos lexicográficamente
(plantilla de función & objeto función de algoritmo)
objeto función restringido que implementa x <=> y
(clase)
compara dos rangos lexicográficamente
(objeto función de algoritmo)