Namespaces
Variants

std::ranges::shift_left, std::ranges::shift_right

De es.cppreference.net
 
 
Biblioteca de algoritmos
Algoritmos restringidos y algoritmos sobre rangos (C++20)
Algoritmos restringidos, p. ej. ranges::copy, ranges::sort, ...
Operaciones de secuencia no modificadoras    
Operaciones por lotes
(C++17)
Operaciones de búsqueda
Operaciones de secuencia modificadoras
Operaciones de copia
(C++11)
(C++11)
Operaciones de intercambio
Operaciones de transformación
Operaciones de generación
Operaciones de eliminación
Operaciones de cambio de orden
(hasta C++17)(C++11)
(C++20)(C++20)
Operaciones de muestreo
(C++17)

Operaciones de ordenación y relacionadas
Operaciones de particionado
(C++11)    

Operaciones de ordenación
Operaciones de búsqueda binaria
(en rangos particionados)
Operaciones de conjunto (sobre rangos ordenados)
Operaciones de mezcla (sobre rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
(C++11)
(C++17)
Operaciones de comparación lexicográfica
Operaciones de permutación


 
Algoritmos restringidos
Todos los nombres en este menú pertenecen al espacio de nombres std::ranges
Operaciones de secuencia no modificadoras
Operaciones de secuencia modificadoras
Operaciones de particionado
Operaciones de ordenación
Operaciones de búsqueda binaria (sobre rangos ordenados)
       
       
Operaciones de conjunto (sobre rangos ordenados)
Operaciones de montículo
Operaciones de mínimo/máximo
       
       
Operaciones de permutación
Operaciones de plegado
Operaciones sobre almacenamiento no inicializado
Tipos de retorno
 
Definido en el encabezado <algorithm>
Firma de llamada
template< std::permutable I, std::sentinel_for<I> S >
constexpr ranges::subrange<I>
    shift_left( I first, S last, std::iter_difference_t<I> n );
(1) (desde C++23)
template< ranges::forward_range R >
requires std::permutable<ranges::iterator_t<R>>
constexpr ranges::borrowed_subrange_t<R>
    shift_left( R&& r, ranges::range_difference_t<R> n );
(2) (desde C++23)
template< std::permutable I, std::sentinel_for<I> S >
constexpr ranges::subrange<I>
    shift_right( I first, S last, std::iter_difference_t<I> n );
(3) (desde C++23)
template< ranges::forward_range R >
requires std::permutable<ranges::iterator_t<R>>
constexpr ranges::borrowed_subrange_t<R>
    shift_right( R&& r, ranges::range_difference_t<R> n );
(4) (desde C++23)

Desplaza los elementos en el rango [first, last) o r en n posiciones. El comportamiento no está definido si [first, last) no es un rango válido.

1) Desplaza los elementos hacia el principio del rango:
  • Si n == 0 || n >= last - first, no hay efectos.
  • Si n < 0, el comportamiento no está definido.
  • De lo contrario, para cada entero i en [0, last - first - n), mueve el elemento originalmente en la posición first + n + i a la posición first + i. Los movimientos se realizan en orden creciente de i empezando desde 0.
3) Desplaza los elementos hacia el final del rango:
  • Si n == 0 || n >= last - first, no hay efectos.
  • Si n < 0, el comportamiento no está definido.
  • De lo contrario, para cada entero i en [0, last - first - n), mueve el elemento originalmente en la posición first + i a la posición first + n + i. Si I modela bidirectional_iterator, entonces los movimientos se realizan en orden decreciente de i empezando desde last - first - n - 1.
2,4) Igual que (1) o (3) respectivamente, pero usa r como el rango, como si se usara ranges::begin(r) como first y ranges::end(r) como last.

Los elementos que están en el rango original pero no en el nuevo rango se quedan en un estado válido pero no especificado.

Las entidades similares a funciones descritas en esta página son objetos función de algoritmo (conocidas informalmente como niebloids), es decir:

Parámetros

first, last - el par iterador-centinela que define el rango de elementos a desplazar
r - el rango de elementos a desplazar
n - el número de posiciones a desplazar

Valor de retorno

1,2) { first, /*NEW_LAST*/ } , donde NEW_LAST es el final del rango resultante y equivalente a:
  • first + ( last - first - n ) , si n es menor que last - first ;
  • first en caso contrario.
3,4) { /*NEW_FIRST*/ , last } , donde NEW_FIRST es el inicio del rango resultante y equivalente a:
  • first + n , si n es menor que last - first ;
  • last en caso contrario.

Complejidad

1,2) Como máximo ranges:: distance ( first, last ) - n asignaciones.
3,4) Como máximo ranges:: distance ( first, last ) - n asignaciones o intercambios.

Notas

ranges::shift_left / ranges::shift_right tiene mejor eficiencia en implementaciones comunes si I modela bidirectional_iterator o (mejor aún) random_access_iterator .

Las implementaciones (por ejemplo, MSVC STL ) pueden habilitar la vectorización cuando el tipo de iterador modela contiguous_iterator y el intercambio de su tipo de valor no llama ni a funciones miembro especiales no triviales ni a ADL -encontrado swap .

Macro de prueba de características Valor Estándar Característica
__cpp_lib_shift 202202L (C++23) std::ranges::shift_left y std::ranges::shift_right

Ejemplo

#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::ranges::shift_left(a, 3);
    std::ranges::shift_left(b, 3);
    std::ranges::shift_left(c, 3);
    std::cout << a << "  " << b << "  " << c << '\n';
    std::ranges::shift_right(a, 2);
    std::ranges::shift_right(b, 2);
    std::ranges::shift_right(c, 2);
    std::cout << a << "  " << b << "  " << c << '\n';
    std::ranges::shift_left(a, 8); // no tiene efecto: n >= last - first
    std::ranges::shift_left(b, 8); // ditto
    std::ranges::shift_left(c, 8); // ditto
    std::cout << a << "  " << b << "  " << c << '\n';
//  std::ranges::shift_left(a, -3); // UB
}

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

mueve un rango de elementos a una nueva ubicación
(objeto función de algoritmo)
mueve un rango de elementos a una nueva ubicación en orden inverso
(objeto función de algoritmo)
rota el orden de los elementos en un rango
(objeto función de algoritmo)
desplaza elementos en un rango
(plantilla de función)