std::rotate - cppreference.com
De cppreference.com
| Definido en el archivo de encabezado |
||
|
|
(1) | (constexpr desde C++20) |
|
|
(2) | (desde C++17) |
1) Realiza una rotación hacia la izquierda en un rango de elementos.
Específicamente, std::rotate intercambia los elementos en el rango [first, last) de tal manera que los elementos en [first, middle) se colocan después de los elementos en [middle, last) mientras que se conserva el orden de los elementos en ambos rangos.
2) Igual que (1), pero ejecutado de acuerdo con la política de ejecución policy.
Esta sobrecarga no participa 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.
Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:
[first,middle)o[middle,last)no es un rango válido.
Parámetros
| first, last | - | El par de iteradores que definen el rango de elementos a rotar |
| middle | - | El elemento que debe aparecer al principio del rango rotado. |
| policy | - | La política de ejecución a usar. Véase política de ejecución para más detalles. |
| Requisitos de tipo | ||
-ForwardIt debe satisfacer los requisitos de IteradorDeAvanceLegado.
| ||
Valor de retorno
El iterador del elemento al que hace referencia originalmente *first, es decir, el siguiente iterador std::distance(middle, last)
ésimo de first.
Complejidad
Como máximo, std::distance(first, last) intercambios.
Excepciones
La sobrecarga con un parámetro de plantilla llamado ExecutionPolicy (política de ejecución) reporta 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éase también las implementaciones en libstdc++, libc++, y MSVC STL.
template<class ForwardIt> constexpr // desde C++20 ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last) { if (first == middle) return last; if (middle == last) return first; ForwardIt write = first; ForwardIt next_read = first; // posición de lectura para cuando “read” llegue a “last” for (ForwardIt read = middle; read != last; ++write, ++read) { if (write == next_read) next_read = read; // rastrear dónde quedó “first” std::iter_swap(write, read); } // rotar la secuencia restante en su lugar rotate(write, next_read, last); return write; }
Notas
std::rotate tiene mejor eficiencia en implementaciones comunes si ForwardIt satisface IteradorBidireccionalLegado o (mejor) IteradorDeAccesoAleatorioLegado.
Las implementaciones (p. ej., MSVC STL) pueden habilitar la vectorización cuando el tipo iterador satisface IteradorContiguoLegado y el intercambio de su tipo valor no llama a una función miembro especial no trivial ni a swap hallada por la búsqueda dependiente de argumento.
Ejemplo
std::rotate es un componente básico común en muchos algoritmos. Este ejemplo demuestra ordenamiento por inserción.
#include <algorithm> #include <iostream> #include <iomanip> #include <vector> auto print = [](const auto remark, const auto& v) { std::cout << remark; for (auto n : v) std::cout << std::setw(2) << n << ' '; std::cout << '\n'; }; int main() { std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1}; print("antes del ordenamiento: ", v); // ordenamiento por inserción for (auto i = v.begin(); i != v.end(); ++i) std::rotate(std::upper_bound(v.begin(), i, *i), i, i + 1); print("después del ordenamiento: ", v); // rotación simple a la izquierda std::rotate(v.begin(), v.begin() + 1, v.end()); print("rotación simple a la izquierda: ", v); // rotación simple a la derecha std::rotate(v.rbegin(), v.rbegin() + 1, v.rend()); print("rotación simple a la derecha: ", v); }
Salida:
antes del ordenamiento: 2 4 2 0 5 10 7 3 7 1 después del ordenamiento: 0 1 2 2 3 4 5 7 7 10 rotación simple a la izquierda: 1 2 2 3 4 5 7 7 10 0 rotación simple a la derecha: 0 1 2 2 3 4 5 7 7 10
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 488 | C++98 | No se devolvía la nueva ubicación del elemento al que apunta first.
|
Se devuelve. |