Namespaces
Variants

std::equal

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 de secuencia modificadoras
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)

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

Operaciones de ordenación
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjunto (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 >
bool equal( InputIt1 first1, InputIt1 last1,
            InputIt2 first2 );
(1) (constexpr desde C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,
            ForwardIt2 first2 );
(2) (desde C++17)
template< class InputIt1, class InputIt2, class BinaryPred >
bool equal( InputIt1 first1, InputIt1 last1,
            InputIt2 first2, BinaryPred p );
(3) (constexpr desde C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class BinaryPred >
bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,
            ForwardIt2 first2, BinaryPred p );
(4) (desde C++17)
template< class InputIt1, class InputIt2 >
bool equal( InputIt1 first1, InputIt1 last1,
            InputIt2 first2, InputIt2 last2 );
(5) (desde C++14)
(constexpr desde C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,
            ForwardIt2 first2, ForwardIt2 last2 );
(6) (desde C++17)
template< class InputIt1, class InputIt2, class BinaryPred >
bool equal( InputIt1 first1, InputIt1 last1,
            InputIt2 first2, InputIt2 last2, BinaryPred p );
(7) (desde C++14)
(constexpr desde C++20)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class BinaryPred >
bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,
            ForwardIt2 first2, ForwardIt2 last2, BinaryPred p );
(8) (desde C++17)

Comprueba si [first1, last1) y un rango que comienza en first2 son iguales:

  • Para las sobrecargas (1-4), el segundo rango tiene std::distance(first1, last1) elementos.
  • Para las sobrecargas (5-8), el segundo rango es [first2, last2).
1,5) Los elementos se comparan usando operator==.
3,7) Los elementos se comparan usando el predicado binario dado p.
2,4,6,8) Igual que (1,3,5,7), pero ejecutadas de acuerdo a policy.
Estas sobrecargas participan en la resolución de sobrecarga solo si el valor de la siguiente expresión es true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(hasta C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(desde C++20)

Parámetros

first1, last1 - el par de iteradores que define el primer rango de elementos a comparar
first2, last2 - el par de iteradores que define el segundo rango de elementos a comparar
policy - la política de ejecución a usar
p - predicado binario que devuelve ​true si los elementos deben ser tratados como iguales.

La firma de la función predicado debe ser equivalente a la siguiente:

bool pred(const Type1 &a, const Type2 &b);

Si bien la firma no necesita tener const &, la función no debe modificar los objetos que se le pasan y debe ser capaz de aceptar todos los valores de tipo (posiblemente const) Type1 y Type2 independientemente de la categoría de valor (por lo tanto, Type1 & no está permitido, ni tampoco Type1 a menos que para Type1 un movimiento sea equivalente a una copia(desde C++11)).
Los tipos Type1 y Type2 deben ser tales que los objetos de tipos InputIt1 y InputIt2 puedan ser desreferenciados y luego convertidos implícitamente a Type1 y Type2 respectivamente. ​

Requisitos de tipo
-
InputIt1, InputIt2 debe cumplir los requisitos de LegacyInputIterator.
-
ForwardIt1, ForwardIt2 debe cumplir los requisitos de LegacyForwardIterator.
-
BinaryPred debe cumplir los requisitos de BinaryPredicate.

Valor de retorno

1-4) Si cada elemento correspondiente en los dos rangos es igual, devuelve true. De lo contrario devuelve false.
5-8) Si std::distance(first1, last1) y std::distance(first2, last2) son iguales, y cada elemento correspondiente en los dos rangos es igual, devuelve true. De lo contrario devuelve false.

Complejidad

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

1) Como máximo N1 comparaciones usando operator==.
2) O(N1) comparaciones usando operator==.
3) Como máximo N1 aplicaciones del predicado p.
4) O(N1) aplicaciones del predicado p.
5-8) Si InputIt1 y InputIt2 son ambos LegacyRandomAccessIterator, y last1 - first1 != last2 - first2 es true, no se realizará ninguna comparación.
De lo contrario, dado N como min(N1,N2):
5) Como máximo N comparaciones usando operator==.
6) O(N) comparaciones usando operator==.
7) Como máximo N aplicaciones del predicado p.
8) O(N) aplicaciones del predicado p.

Excepciones

Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy reportan errores de la siguiente manera:

  • Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y ExecutionPolicy es una de las políticas estándar, se llama a std::terminate. Para cualquier otro ExecutionPolicy, el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.

Posible implementación

equal (1)
template<class InputIt1, class InputIt2>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
{
    for (; first1 != last1; ++first1, ++first2)
        if (!(*first1 == *first2))
            return false;
    
    return true;
}
equal (3)
template<class InputIt1, class InputIt2, class BinaryPred>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1,
           InputIt2 first2, BinaryPred p)
{
    for (; first1 != last1; ++first1, ++first2)
        if (!p(*first1, *first2))
            return false;
    
    return true;
}
equal (5)
namespace detail
{
    // random-access iterator implementation (allows quick range size detection)
    template<class RandomIt1, class RandomIt2>
    constexpr //< since C++20
    bool equal(RandomIt1 first1, RandomIt1 last1, RandomIt2 first2, RandomIt2 last2,
               std::random_access_iterator_tag, std::random_access_iterator_tag)
    {
        if (last1 - first1 != last2 - first2)
            return false;
        
        for (; first1 != last1; ++first1, ++first2)
            if (!(*first1 == *first2))
                return false;
        
        return true;
    }
    
    // input iterator implementation (needs to manually compare with “last2”)
    template<class InputIt1, class InputIt2>
    constexpr //< since C++20
    bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
               std::input_iterator_tag, std::input_iterator_tag)
    {
        for (; first1 != last1 && first2 != last2; ++first1, ++first2)
            if (!(*first1 == *first2))
                return false;
        
        return first1 == last1 && first2 == last2;
    }
}

template<class InputIt1, class InputIt2>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
{
    details::equal(first1, last1, first2, last2,
                   typename std::iterator_traits<InputIt1>::iterator_category(),
                   typename std::iterator_traits<InputIt2>::iterator_category());
}
equal (7)
namespace detail
{
    // random-access iterator implementation (allows quick range size detection)
    template<class RandomIt1, class RandomIt2, class BinaryPred>
    constexpr //< since C++20
    bool equal(RandomIt1 first1, RandomIt1 last1,
               RandomIt2 first2, RandomIt2 last2, BinaryPred p,
               std::random_access_iterator_tag, std::random_access_iterator_tag)
    {
        if (last1 - first1 != last2 - first2)
            return false;
        
        for (; first1 != last1; ++first1, ++first2)
            if (!p(*first1, *first2))
                return false;
        
        return true;
    }
    
    // input iterator implementation (needs to manually compare with “last2”)
    template<class InputIt1, class InputIt2, class BinaryPred>
    constexpr //< since C++20
    bool equal(InputIt1 first1, InputIt1 last1,
               InputIt2 first2, InputIt2 last2, BinaryPred p,
               std::input_iterator_tag, std::input_iterator_tag)
    {
        for (; first1 != last1 && first2 != last2; ++first1, ++first2)
            if (!p(*first1, *first2))
                return false;
        
        return first1 == last1 && first2 == last2;
    }
}

template<class InputIt1, class InputIt2, class BinaryPred>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1,
           InputIt2 first2, InputIt2 last2, BinaryPred p)
{
    details::equal(first1, last1, first2, last2, p,
                   typename std::iterator_traits<InputIt1>::iterator_category(),
                   typename std::iterator_traits<InputIt2>::iterator_category());
}

Notas

std::equal no debe usarse para comparar los rangos formados por los iteradores de std::unordered_set, std::unordered_multiset, std::unordered_map, o std::unordered_multimap porque el orden en que los elementos se almacenan en esos contenedores puede ser diferente incluso si los dos contenedores almacenan los mismos elementos.

Al comparar contenedores completos o vistas de cadena(desde C++17) por igualdad, operator== para el tipo correspondiente suele ser preferido.

La std::equal secuencial no está garantizada que sea de cortocircuito. Por ejemplo, si el primer par de elementos de ambos rangos no se comparan igual, el resto de elementos también puede ser comparados. La comparación sin cortocircuito puede ocurrir cuando los rangos se comparan con std::memcmp o algoritmos vectorizados específicos de la implementación.

Ejemplo

El siguiente código usa std::equal para comprobar si una cadena es un palíndromo.

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string_view>

constexpr bool is_palindrome(const std::string_view& s)
{
    return std::equal(s.cbegin(), s.cbegin() + s.size() / 2, s.crbegin());
}

void test(const std::string_view& s)
{
    std::cout << std::quoted(s)
              << (is_palindrome(s) ? " is" : " is not")
              << " a palindrome\n";
}

int main()
{
    test("radar");
    test("hello");
}

Salida:

"radar" is a palindrome
"hello" is not a palindrome

Véase también

encuentra el primer elemento que satisface criterios específicos
(plantilla de función & objeto función de algoritmo)
compara dos rangos lexicográficamente
(plantilla de función & objeto función de algoritmo)
encuentra la primera posición donde dos rangos difieren
(plantilla de función & objeto función de algoritmo)
busca la primera aparición de un rango de elementos
(plantilla de función & objeto función de algoritmo)
determina si dos conjuntos de elementos son iguales
(objeto función de algoritmo)
objeto función que implementa x == y
(plantilla de clase)
encuentra el rango de elementos que coinciden con un valor dado usando búsqueda binaria
(plantilla de función & objeto función de algoritmo)