std::shift_left, std::shift_right
De es.cppreference.net
| Definido en el encabezado <algorithm>
|
||
template< class ForwardIt >
constexpr ForwardIt shift_left( ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(1) | (desde C++20) |
template< class ExecutionPolicy, class ForwardIt >
ForwardIt shift_left( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(2) | (desde C++20) |
template< class ForwardIt >
constexpr ForwardIt shift_right( ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(3) | (desde C++20) |
template< class ExecutionPolicy, class ForwardIt >
ForwardIt shift_right( ExecutionPolicy&& policy,
ForwardIt first, ForwardIt last,
typename std::iterator_traits<ForwardIt>::
difference_type n );
|
(4) | (desde C++20) |
Desplaza los elementos en el rango [first, last) en n posiciones.
1) Desplaza los elementos hacia el inicio del rango.
- Si
n == 0 || n >= last - first, no hay efectos. - De lo contrario, para cada entero
ien[0,last - first - n), mueve el elemento originalmente en la posiciónfirst + n + ia la posiciónfirst + i.
Los movimientos se realizan en orden creciente de
i comenzando desde 0.3) Desplaza los elementos hacia el final del rango.
- Si
n == 0 || n >= last - first, no hay efectos. - De lo contrario, para cada entero
ien[0,last - first - n), mueve el elemento originalmente en la posiciónfirst + ia la posiciónfirst + n + i.
Si
ForwardIt cumple con los requisitos de LegacyBidirectionalIterator, entonces los movimientos se realizan en orden decreciente de i comenzando desde last - first - n - 1.2,4) Igual que (1) y (3), respectivamente, pero ejecutados de acuerdo con
policy y los movimientos pueden realizarse en cualquier orden. Estas sobrecargas participan en la resolución de sobrecarga solo si
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> es true.Los elementos que están en el rango original pero no en el nuevo rango se dejan en un estado válido pero no especificado.
Si se cumple alguna de las siguientes condiciones, el comportamiento no está definido:
n >= 0no estrue.- El tipo de
*firstno es MoveAssignable. - Para
shift_right,ForwardItno es LegacyBidirectionalIterator ni ValueSwappable.
Parámetros
| first, last | - | el par de iteradores que define el rango de elementos a desplazar |
| n | - | el número de posiciones a desplazar |
| policy | - | la política de ejecución a utilizar |
| Requisitos de tipo | ||
-
ForwardIt
debe cumplir con los requisitos de
LegacyForwardIterator
.
|
||
Valor de retorno
1,2)
El final del rango resultante.
- Si n es menor que std:: distance ( first, last ) , retorna un iterador igual a std:: next ( first, ( std:: distance ( first, last ) - n ) ) .
- De lo contrario, retorna first .
3,4)
El inicio del rango resultante.
- Si n es menor que std:: distance ( first, last ) , devuelve un iterador igual a std:: next ( first, n ) .
- De lo contrario, devuelve last .
Complejidad
1,2)
Como máximo
std::
distance
(
first, last
)
-
n
asignaciones.
3,4)
Como máximo
std::
distance
(
first, last
)
-
n
asignaciones o intercambios.
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.
Notas
| Macro de prueba de características | Valor | Std | Característica |
|---|---|---|---|
__cpp_lib_shift
|
201806L
|
(C++20) |
std::shift_left
y
std::shift_right
|
Ejemplo
Ejecutar este código
#include <algorithm> #include <iostream> #include <string> #include <type_traits> #include <vector> struct S { int value{0}; bool specified_state{true}; S(int v = 0) : value{v} {} S(S const& rhs) = default; S(S&& rhs) { *this = std::move(rhs); } S& operator=(S const& rhs) = default; S& operator=(S&& rhs) { if (this != &rhs) { value = rhs.value; specified_state = rhs.specified_state; rhs.specified_state = false; } return *this; } }; template<typename T> std::ostream& operator<<(std::ostream& os, std::vector<T> const& v) { for (const auto& s : v) { if constexpr (std::is_same_v<T, S>) s.specified_state ? os << s.value << ' ' : os << ". "; else if constexpr (std::is_same_v<T, std::string>) os << (s.empty() ? "." : s) << ' '; else os << s << ' '; } return os; } int main() { std::cout << std::left; std::vector<S> a{1, 2, 3, 4, 5, 6, 7}; std::vector<int> b{1, 2, 3, 4, 5, 6, 7}; std::vector<std::string> c{"α", "β", "γ", "δ", "ε", "ζ", "η"}; std::cout << "vector<S> \tvector<int> \tvector<string>\n"; std::cout << a << " " << b << " " << c << '\n'; std::shift_left(begin(a), end(a), 3); std::shift_left(begin(b), end(b), 3); std::shift_left(begin(c), end(c), 3); std::cout << a << " " << b << " " << c << '\n'; std::shift_right(begin(a), end(a), 2); std::shift_right(begin(b), end(b), 2); std::shift_right(begin(c), end(c), 2); std::cout << a << " " << b << " " << c << '\n'; std::shift_left(begin(a), end(a), 8); // no tiene efecto: n >= last - first std::shift_left(begin(b), end(b), 8); // ditto std::shift_left(begin(c), end(c), 8); // ditto std::cout << a << " " << b << " " << c << '\n'; // std::shift_left(begin(a), end(a), -3); // UB, e.g. segfault }
Salida posible:
vector<S> vector<int> vector<string> 1 2 3 4 5 6 7 1 2 3 4 5 6 7 α β γ δ ε ζ η 4 5 6 7 . . . 4 5 6 7 5 6 7 δ ε ζ η . . . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η . . . 4 5 6 7 . 4 5 4 5 6 7 5 . . δ ε ζ η .
Véase también
(C++11) |
mueve un rango de elementos a una nueva ubicación (plantilla de función & objeto de función de algoritmo) |
(C++20) |
|
(C++11) |
mueve un rango de elementos a una nueva ubicación en orden inverso (plantilla de función & objeto de función de algoritmo) |
(C++20) |
|
| rota el orden de los elementos en un rango (plantilla de función & objeto de función de algoritmo) | |
(C++20) |
|
(C++23)(C++23) |
desplaza elementos en un rango (objeto de función de algoritmo) |