std::equal
| 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).
operator==.p.policy.true:
|
|
(hasta C++20) |
|
|
(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:
Si bien la firma no necesita tener |
| 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
true. De lo contrario devuelve false.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):
operator==.operator==.p.p.InputIt1 y InputIt2 son ambos LegacyRandomAccessIterator, y last1 - first1 != last2 - first2 es true, no se realizará ninguna comparación.operator==.operator==.p.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
ExecutionPolicyes una de las políticas estándar, se llama a std::terminate. Para cualquier otroExecutionPolicy, 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
(C++11) |
encuentra el primer elemento que satisface criterios específicos (plantilla de función & objeto función de algoritmo) |
(C++20)(C++20)(C++20) |
|
| 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) | |
(C++20) |
|
| busca la primera aparición de un rango de elementos (plantilla de función & objeto función de algoritmo) | |
(C++20) |
|
(C++20) |
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) | |
(C++20) |