std:: equal
|
Definido en el encabezado
<algorithm>
|
||
|
template
<
class
InputIt1,
class
InputIt2
>
bool
equal
(
InputIt1 first1, InputIt1 last1,
|
(1) | (constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2
>
bool
equal
(
ExecutionPolicy
&&
policy,
|
(2) | (desde C++17) |
|
template
<
class
InputIt1,
class
InputIt2,
class
BinaryPred
>
bool
equal
(
InputIt1 first1, InputIt1 last1,
|
(3) | (constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
class
BinaryPred
>
|
(4) | (desde C++17) |
|
template
<
class
InputIt1,
class
InputIt2
>
bool
equal
(
InputIt1 first1, InputIt1 last1,
|
(5) |
(desde C++14)
(constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2
>
bool
equal
(
ExecutionPolicy
&&
policy,
|
(6) | (desde C++17) |
|
template
<
class
InputIt1,
class
InputIt2,
class
BinaryPred
>
bool
equal
(
InputIt1 first1, InputIt1 last1,
|
(7) |
(desde C++14)
(constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt1,
class
ForwardIt2,
class
BinaryPred
>
|
(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).
|
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)
|
| 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
Complejidad
Dado N 1 como std:: distance ( first1, last1 ) y N 2 como std:: distance ( first2, last2 ) :
InputIt1
y
InputIt2
son ambos
LegacyRandomAccessIterator
, y
last1
-
first1
!
=
last2
-
first2
es
true
, no se realizará ninguna comparación.
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 uno de los standard policies , std::terminate es llamado. Para cualquier otroExecutionPolicy, 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
|
(C++11)
|
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) |
|
|
(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) |
|
|
devuelve el rango de elementos que coinciden con una clave específica
(plantilla de función) |