std:: unique
|
Definido en el encabezado
<algorithm>
|
||
|
template
<
class
ForwardIt
>
ForwardIt unique ( ForwardIt first, ForwardIt last ) ; |
(1) | (constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt
>
ForwardIt unique
(
ExecutionPolicy
&&
policy,
|
(2) | (desde C++17) |
|
template
<
class
ForwardIt,
class
BinaryPred
>
ForwardIt unique ( ForwardIt first, ForwardIt last, BinaryPred p ) ; |
(3) | (constexpr desde C++20) |
|
template
<
class
ExecutionPolicy,
class
ForwardIt,
class
BinaryPred
>
|
(4) | (desde C++17) |
Elimina todos excepto el primer elemento de cada grupo consecutivo de elementos equivalentes del rango
[
first
,
last
)
y retorna un iterador más allá del final para el nuevo límite del rango.
|
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 |
Explicación
La eliminación se realiza desplazando los elementos en el rango de tal manera que los elementos que no se deben eliminar aparezcan al principio del rango.
- El desplazamiento se realiza mediante copy assignment (until C++11) move assignment (since C++11) .
- La operación de eliminación es estable: el orden relativo de los elementos que no se eliminan permanece igual.
-
La secuencia subyacente de
[first,last)no se acorta mediante la operación de eliminación. Dado result como el iterador devuelto:
-
-
Todos los iteradores en
[result,last)siguen siendo dereferenceable .
-
Todos los iteradores en
|
(desde C++11) |
Parámetros
| first, last | - | el par de iteradores que define el rango de elementos a procesar |
| 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 la 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 | ||
-
ForwardIt
debe cumplir con los requisitos de
LegacyForwardIterator
.
|
||
-
ForwardIt
debe cumplir con los requisitos de
MoveAssignable
.
|
||
Valor de retorno
Un
ForwardIt
al nuevo final del rango.
Complejidad
Dado N como std:: distance ( first, last ) :
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
Consulte también las implementaciones en libstdc++ , libc++ , y MSVC STL .
| único (1) |
|---|
template<class ForwardIt> ForwardIt unique(ForwardIt first, ForwardIt last) { if (first == last) return last; ForwardIt result = first; while (++first != last) if (!(*result == *first) && ++result != first) *result = std::move(*first); return ++result; } |
| único (3) |
template<class ForwardIt, class BinaryPredicate> ForwardIt unique(ForwardIt first, ForwardIt last, BinaryPredicate p) { if (first == last) return last; ForwardIt result = first; while (++first != last) if (!p(*result, *first) && ++result != first) *result = std::move(*first); return ++result; } |
Notas
Una llamada a
unique
normalmente va seguida de una llamada a la función miembro
erase
del contenedor para eliminar realmente los elementos del contenedor.
Ejemplo
#include <algorithm> #include <iostream> #include <vector> int main() { // un vector que contiene varios elementos duplicados std::vector<int> v{1, 2, 1, 1, 3, 3, 3, 4, 5, 4}; auto print = [&](int id) { std::cout << "@" << id << ": "; for (int i : v) std::cout << i << ' '; std::cout << '\n'; }; print(1); // eliminar duplicados consecutivos (adyacentes) auto last = std::unique(v.begin(), v.end()); // v ahora contiene {1 2 1 3 4 5 4 x x x}, donde 'x' es indeterminado v.erase(last, v.end()); print(2); // ordenar seguido de unique, para eliminar todos los duplicados std::sort(v.begin(), v.end()); // {1 1 2 3 4 4 5} print(3); last = std::unique(v.begin(), v.end()); // v ahora contiene {1 2 3 4 5 x x}, donde 'x' es indeterminado v.erase(last, v.end()); print(4); }
Salida:
@1: 1 2 1 1 3 3 3 4 5 4 @2: 1 2 1 3 4 5 4 @3: 1 1 2 3 4 4 5 @4: 1 2 3 4 5
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 202 | C++98 |
el comportamiento no estaba claro si los elementos
se comparan usando una relación no de equivalencia |
el comportamiento es
indefinido en este caso |
Véase también
|
encuentra los dos primeros elementos adyacentes que son iguales (o satisfacen un predicado dado)
(plantilla de función) |
|
|
crea una copia de un rango de elementos que no contiene duplicados consecutivos
(plantilla de función) |
|
|
elimina elementos que cumplen criterios específicos
(plantilla de función) |
|
|
elimina elementos duplicados consecutivos
(función miembro pública de
std::list<T,Allocator>
)
|
|
|
elimina elementos duplicados consecutivos
(función miembro pública de
std::forward_list<T,Allocator>
)
|
|
|
(C++20)
|
elimina elementos duplicados consecutivos en un rango
(objeto función de algoritmo) |