std::rotate
| Definido en el archivo de encabezado <algorithm>
|
||
template< class ForwardIt > ForwardIt rotate( ForwardIt first, ForwardIt middle, ForwardIt last ); |
(1) | (constexpr desde C++20) |
template< class ExecutionPolicy, class ForwardIt > ForwardIt rotate( ExecutionPolicy&& policy, ForwardIt first, ForwardIt middle, ForwardIt last ); |
(2) | (desde C++17) |
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.policy.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.
|
(hasta C++11) |
|
(desde C++11) |
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. |
Véase también
| Copia y rota un rango de elementos. (plantilla de función) | |
(C++20) |
Rota el orden de los elementos en un rango. (niebloid) |