std::unique - cppreference.com
| Definido en el archivo de encabezado |
||
|
(1) | (constexpr desde C++20) |
|
|
(2) | (desde C++17) |
|
(3) | (constexpr desde C++20) |
|
|
(4) | (desde C++17) |
Elimina todos los elementos excepto el primero de cada grupo consecutivo de elementos equivalentes del rango [first, last) y devuelve un iterador posterior al final para el nuevo final del rango.
1) Los elementos se comparan utilizando operator==.
3) Los elementos se comparan utilizando el predicado binario dado p.
Si p no establece una relación de equivalencia, el comportamiento no está definido.
2,4) Igual que (1,3), pero ejecutado de acuerdo con policy.
Estas sobrecargas no participan en la resolución de sobrecarga a menos que 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) sea verdadera.
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 la asignación de copia (hasta C++11)asignación de movimiento (desde C++11).
- La operación de eliminación es estable: el orden relativo de los elementos que no se deben eliminar permanece igual.
- La secuencia subyacente de
[first,last)no se acorta con la operación de eliminación. Dadoresultcomo el iterador devuelto:
- Todos los iteradores en
[result,last)siguen siendo desreferenciables.
- Todos los iteradores en
|
(desde C++11) |
Parámetros
| first, last | - | El rango de elementos a procesar. |
| policy | - | La política de ejecución a usar. Véase política de ejecución para más detalles. |
| p | - | Predicado binario que devuelve true si los elementos deben tratarse como iguales.
La signatura de la función predicado deberá ser equivalente a la siguiente:
Mientras que la signatura no necesita tener |
| Requisitos de tipo | ||
-ForwardIt debe satisfacer los requisitos de ForwardIterator.
| ||
-El tipo del ForwardIt desreferenciado debe cumplir con los requisitos de AsignablePorMovimiento.
| ||
Return value
Un ForwardIt al nuevo final del rango.
Complexity
Dada N as std::distance(first, last):
1,2) Exactamente max(0,N-1) comparaciones usando operator==.
3,4) Exactamente max(0,N-1) aplicaciones del predicado p.
Excepciones
Las sobrecargas con un parámetro de plantilla llamado ExecutionPolicy (política de ejecución) reportan errores tales que:
- Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y la política de ejecución es una de las tres políticas estándar, se llama a std::terminate. Para cualquier otra política de ejecución, el comportamiento está definido por la implementación.
- Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.
Posible implementación
Véanse también las implementaciones en libstdc++, libc++, y MSVC STL.
| unique (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; } |
| unique (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 suele ir seguida de una llamada a la función miembro erase de un contenedor para eliminar elementos del contenedor.
Ejemplo
#include <algorithm> #include <iostream> #include <vector> int main() { // una 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 alberga {1 2 1 3 4 5 4 x x x}, donde 'x' es indeterminada v.erase(last, v.end()); print(2); // sort 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 alberga {1 2 3 4 5 x x}, donde 'x' es indeterminada 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 de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
| ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 202 | C++98 | El comportamiento no estaba claro si los elementos se comparan utilizando una relación de no equivalencia, |
El comportamiento no está definido en este caso. |
Véase también
| Encuentra dos elementos contiguos idénticos (o que satisfagan un predicado dado). (plantilla de función) [editar] | |
| Crea una copia de un rango de elementos que no contiene duplicados consecutivos. (plantilla de función) [editar] | |
| Elimina elementos que satisfacen un criterio específico. (plantilla de función) [editar] | |
| Elimina elementos consecutivos duplicados. (función miembro pública de std::list) [editar]
| |
(C++11) |
Elimina elementos consecutivos duplicados. (función miembro pública de std::forward_list) [editar]
|
(C++20) |
Elimina elementos duplicados consecutivos en un rango. (niebloid) [editar] |