std::ranges::prev
| 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:
- Las listas de argumentos de plantilla explícitas no se pueden especificar al llamar a cualquiera de ellas.
- Ninguna de ellas es visible para la búsqueda dependiente de argumentos.
- Cuando alguna de ellas se encuentra mediante la búsqueda normal no calificada como el nombre a la izquierda del operador de llamada a función, se inhibe la búsqueda dependiente de argumentos.
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
i.nésimo predecesor del iterador i.nésimo predecesor del iterador i, o el primer iterador equivalente a bound, lo que suceda primero.Complejidad
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
(C++20) |
Incrementa un iterador en una distancia dada o a un límite. (niebloid) |
(C++20) |
Avanza un iterador en una distancia dada o a un límite dado. (niebloid) |
(C++11) |
Decrementa un iterador. (función) |