Namespaces
Variants

std:: equal

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
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 desde 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 utilizando operator == .
3,7) Los elementos se comparan utilizando el predicado binario dado p .
2,4,6,8) Igual que (1,3,5,7) , pero ejecutado según la policy .
Estas sobrecargas participan en la resolución de sobrecarga solo si se cumplen todas las siguientes condiciones:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> es true .

(hasta C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> es true .

(desde C++20)

Contenidos

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 utilizar
p - predicado binario que retorna ​ true si los elementos deben tratarse como iguales.

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

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

Aunque la firma no necesita tener const & , la función no debe modificar los objetos pasados a ella y debe poder 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 deben cumplir con los requisitos de LegacyInputIterator .
-
ForwardIt1, ForwardIt2 deben cumplir con los requisitos de LegacyForwardIterator .
-
BinaryPred deben cumplir con 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, retorna true . De lo contrario retorna false .

Complejidad

Dado N 1 como std:: distance ( first1, last1 ) y N 2 como std:: distance ( first2, last2 ) :

1) Como máximo N 1 comparaciones usando operator == .
2) O(N 1 ) comparaciones usando operator == .
3) Como máximo N 1 aplicaciones del predicado p .
4) O(N 1 ) 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(N 1 ,N 2 ) :
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 uno de los standard policies , std::terminate es llamado. Para cualquier otro ExecutionPolicy , el comportamiento está definido por la implementación.
  • Si el algoritmo falla al asignar memoria, std::bad_alloc es lanzado.

Implementación posible

equal (1)
template<class InputIt1, class InputIt2>
constexpr //< desde 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 //< desde 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
{
    // implementación de iterador de acceso aleatorio (permite detección rápida del tamaño del rango)
    template<class RandomIt1, class RandomIt2>
    constexpr //< desde 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;
    }
    // implementación de iterador de entrada (necesita comparar manualmente con "last2")
    template<class InputIt1, class InputIt2>
    constexpr //< desde 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 //< desde 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
{
    // implementación de iterador de acceso aleatorio (permite detección rápida del tamaño del rango)
    template<class RandomIt1, class RandomIt2, class BinaryPred>
    constexpr //< desde 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;
    }
    // implementación de iterador de entrada (necesita comparar manualmente con "last2")
    template<class InputIt1, class InputIt2, class BinaryPred>
    constexpr //< desde 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 //< desde 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 utilizarse 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 se almacenan los elementos en esos contenedores puede ser diferente incluso si ambos contenedores almacenan los mismos elementos.

Al comparar contenedores completos o string views (since C++17) para igualdad, operator == para el tipo correspondiente generalmente es preferido.

Sequential std::equal no garantiza ser de cortocircuito. Por ejemplo, si el primer par de elementos de ambos rangos no son iguales, el resto de elementos también podría compararse. 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 utiliza 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)
devuelve true si un rango es lexicográficamente menor que otro
(plantilla de función)
encuentra la primera posición donde dos rangos difieren
(plantilla de función)
busca la primera ocurrencia de un rango de elementos
(plantilla de función)
determina si dos conjuntos de elementos son iguales
(objeto función de algoritmo)
objeto función que implementa x == y
(plantilla de clase)
devuelve el rango de elementos que coinciden con una clave específica
(plantilla de función)