Namespaces
Variants

std::ranges:: prev

From cppreference.net
Iterator library
Iterator concepts
Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11) (C++14)
(C++14) (C++14)
(C++11) (C++14)
(C++14) (C++14)
(C++17) (C++20)
(C++17)
(C++17)
Definido en el encabezado <iterator>
Firma de 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 th predecesor del iterador i .

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

i - un iterador
n - número de elementos i debe descender
bound - iterador que denota el inicio del rango i apunta a

Valor de retorno

1) El predecesor de i .
2) El n ésimo predecesor del iterador i .
3) El n th predecesor del iterador i , o el primer iterador que compare igual a bound , el que ocurra primero.

Complejidad

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

Implementación posible

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 está garantizado que lo haga: r. end ( ) es una expresión rvalue, y no existe ningún requisito de iterador que especifique que el decremento de un rvalue esté garantizado para funcionar. En particular, cuando los iteradores se implementan como punteros o su operator-- está calificado como referencia a lvalue, -- r. end ( ) no compila, mientras que ranges :: prev ( r. end ( ) ) sí lo hace.

Esto se ve aún más agravado 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 , y por lo tanto -- r. end ( ) no 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 por una distancia dada o hasta un límite
(objeto función de algoritmo)
avanza un iterador por una distancia dada o hasta un límite dado
(objeto función de algoritmo)
(C++11)
decrementa un iterador
(plantilla de función)