Espacios de nombres
Variantes

std::ranges::prev

De cppreference.com
 
 
Biblioteca de iteradores
Conceptos de iteradores
Primitivas de iteradores
Conceptos de algoritmos y servicios
Conceptos invocables indirectos
Requerimientos comunes de algoritmos
Servicios
Adaptadores de iteradores
Iteradores de flujos
Puntos de personalización de iteradores
Operaciones de iteradores
(C++11)
(C++11)
Acceso a rangos
(C++11)(C++14)
(C++11)(C++14)
(C++17)(C++20)
(C++14)(C++14)
(C++14)(C++14)
(C++17)
(C++17)
 
<tbody> </tbody>
Definido en el archivo de encabezado <iterator>
Signatura de la llamada
template< std::bidirectional_iterator I > constexpr I prev( I i );
(1) (desde C++20)
template< std::bidirectional_iterator I > constexpr I prev( I i, std::iter_difference_t<I> n );
(2) (desde C++20)
template< std::bidirectional_iterator I > constexpr I prev( I i, std::iter_difference_t<I> n, I bound );
(3) (desde C++20)

Devuelve el nésimo predecesor del iterador i.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Parámetros

it - Un iterador.
n - Número de elementos a retroceder.
bound - Centinela que denota el comienzo del rango al que apunta i.

Valor de retorno

1) El predecesor del iterador i.
2) El nésimo predecesor del iterador i.
3) El nésimo predecesor del iterador i, o el primer iterador equivalente a bound, lo que suceda primero.

Complejidad

1) Constante.
2,3) Constante si I modela std::random_access_iterator<I>; lineal de lo contrario.

Posible implementación

struct prev_fn
{
    template<std::bidirectional_iterator I>
    constexpr I operator()(I i) const
    {
        --i;
        return i;
    }

    template<std::bidirectional_iterator I>
    constexpr I operator()(I i, std::iter_difference_t<I> n) const
    {
        ranges::advance(i, -n);
        return i;
    }

    template<std::bidirectional_iterator I>
    constexpr I operator()(I i, std::iter_difference_t<I> n, I bound) const
    {
        ranges::advance(i, -n, bound);
        return i;
    }
};

inline constexpr auto prev = prev_fn();

Notas

Aunque la expresión --r.end() suele compilarse para contenedores, no se garantiza que lo haga: r.end() es una expresión r-valor y no hay ningún requisito de iterador que especifique que se garantiza que la disminución de un r-valor funcione. En particular, cuando los iteradores se implementan como punteros o su operator-- está calificado como referencia a l-valor, --r.end() no se compila, mientras que ranges::prev(r.end()) sí lo hace.

Esto se ve agravado aún más por los rangos que no modelan ranges::common_range. Por ejemplo, para algunos rangos subyacentes, ranges::transform_view::end no tiene el mismo tipo de retorno que ranges::transform_view::begin, por lo que --r.end() no se compilará. Esto no es algo en lo que ranges::prev pueda ayudar, pero existen soluciones alternativas.

Ejemplo

#include <iostream>
#include <iterator>
#include <vector>

int main() 
{
    std::vector<int> v{3, 1, 4};
    auto pv = std::ranges::prev(v.end(), 2);
    std::cout << *pv << '\n';

    pv = std::ranges::prev(pv, 42, v.begin());
    std::cout << *pv << '\n';
}

Salida:

1
3

Véase también

Incrementa un iterador en una distancia dada o a un límite.
(niebloid) [editar]
Avanza un iterador en una distancia dada o a un límite dado.
(niebloid) [editar]
(C++11)
Decrementa un iterador.
(función) [editar]