Espacios de nombres
Variantes
Acciones

std::ranges::advance

De cppreference.com
< cpp‎ | iterator
 
 
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
ranges::advance
(C++20)
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)
 
Definido en el archivo de encabezado <iterator>
Signatura de la llamada
template<std::input_or_output_iterator I >
constexprvoid advance( I& i, std::iter_difference_t<I> n );
(1) (desde C++20)
template<std::input_or_output_iterator I, std::sentinel_for<I> S >
constexprvoid advance( I& i, S bound );
(2) (desde C++20)
template<std::input_or_output_iterator I, std::sentinel_for<I> S >
constexprstd::iter_difference_t<I> advance( I& i, std::iter_difference_t<I> n, S bound );
(3) (desde C++20)
1) Incrementa el iterador dado in veces.
2) Incrementa el iterador dado i hasta que i == bound.
3) Incrementa el iterador dado in veces, o hasta que i == bound, lo que suceda primero.

Si n es negativo, el iterador se decrementa. En este caso, I debe modelar std::bidirectional_iterator y S debe ser del mismo tipo que I si se proporciona bound; de lo contrario, el comportamiento no está definido.

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.

Contenido

[editar]Parámetros

i - El iterador a avanzar.
bound - Centinela que denota el fin del rango del que i es un iterador.
n - Número máximo de incrementos de i.

[editar]Valor de retorno

3) La diferencia entre n y la distancia real i recorrida.

[editar]Complejidad

Lineal.

Sin embargo, si I además modela std::random_access_iterator, o S modela std::sized_sentinel_for<I>, o I y S modelan std::assignable_from<I&, S>, la complejidad es constante.

[editar]Notas

El comportamiento no está definido si la secuencia especificada de incrementos o decrementos requiere que se incremente un iterador no incrementable (como el iterador posterior al final) o que se decremente un iterador no decrementable (como el iterador frontal o el iterador singular).

[editar]Posible implementación

struct advance_fn {template<std::input_or_output_iterator I>constexprvoid operator()(I& i, std::iter_difference_t<I> n)const{ifconstexpr(std::random_access_iterator<I>) i += n;else{while(n >0){--n;++i;}   ifconstexpr(std::bidirectional_iterator<I>){while(n <0){++n;--i;}}}}   template<std::input_or_output_iterator I, std::sentinel_for<I> S>constexprvoid operator()(I& i, S bound)const{ifconstexpr(std::assignable_from<I&, S>) i = std::move(bound);elseifconstexpr(std::sized_sentinel_for<S, I>)(*this)(i, bound - i);elsewhile(i != bound)++i;}   template<std::input_or_output_iterator I, std::sentinel_for<I> S>constexprstd::iter_difference_t<I> operator()(I& i, std::iter_difference_t<I> n, S bound)const{ifconstexpr(std::sized_sentinel_for<S, I>){// std::abs no es constexpr hasta C++23auto abs =[](conststd::iter_difference_t<I> x){return x <0?-x : x;};   if(constauto dist = abs(n)- abs(bound - i); dist <0){(*this)(i, bound);return-dist;}   (*this)(i, n);return0;}else{while(n >0&& i != bound){--n;++i;}   ifconstexpr(std::bidirectional_iterator<I>){while(n <0&& i != bound){++n;--i;}}   return n;}}};   inlineconstexprauto advance = advance_fn();

[editar]Ejemplo

#include <iostream>#include <iterator>#include <vector>   int main(){std::vector<int> v {3, 1, 4};   auto vi = v.begin();   std::ranges::advance(vi, 2);std::cout<<"1) value: "<<*vi <<'\n'<<std::boolalpha;   std::ranges::advance(vi, v.end());std::cout<<"2) vi == v.end(): "<<(vi == v.end())<<'\n';   std::ranges::advance(vi, -3);std::cout<<"3) value: "<<*vi <<'\n';   std::cout<<"4) diff: "<< std::ranges::advance(vi, 2, v.end())<<", value: "<<*vi <<'\n';   std::cout<<"5) diff: "<< std::ranges::advance(vi, 4, v.end())<<", vi == v.end(): "<<(vi == v.end())<<'\n';}

Salida:

1) value: 4 2) vi == v.end(): true 3) value: 3 4) diff: 0, value: 4 5) diff: 3, vi == v.end(): true

[editar]Véase también

Incrementa un iterador en una distancia dada o a un límite.
(niebloid)[editar]
Decrementa un iterador en una distancia dada o a un límite.
(niebloid)[editar]
Devuelve la distancia entre un iterador y un centinela, o entre el principio y el fin de un rango.
(niebloid)[editar]
Avanza un iterador en una distancia determinada.
(función)[editar]
close