Espacios de nombres
Variantes
Acciones

std::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
advance
(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)
 
Definido en el archivo de encabezado <iterator>
template<typename InputIt, typename Distance>
void advance( InputIt& it, Distance n );
(hasta C++17)
template<typename InputIt, typename Distance>
constexpr void advance( InputIt& it, Distance n );
(desde C++17)

Incrementa un iterador dado it en n elementos.

Si n is negativa, el iterador se decrementa. En este caso, InputIt debe de satisfacer los requisitos de BidirectionalIterator, de otra forma el comportamiento no está definido.

Contenido

[editar] Parámetros

it - Iterador a avanzar.
n - Número de elementos en los que it se debe avanzar.
Requisitos de tipo
-
InputIt debe satisfacer los requisitos de InputIterator.

[editar] Valor de retorno

(ninguno)

[editar] Complejidad

Lineal.

Sin embargo, si InputIt cumple con los requisitos de RandomAccessIterator, la complejidad es constante.

[editar] Notas

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

[editar] Posible implementación

Véanse también las implementaciones en libstdc++ y libc++.


Versión no constexpr
namespace detail
{
    template<class It>
    void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
                    std::input_iterator_tag)
    {
        while (n > 0)
        {
            --n;
            ++it;
        }
    }
 
    template<class It>
    void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
                    std::bidirectional_iterator_tag)
    {
        while (n > 0)
        {
            --n;
            ++it;
        }
        while (n < 0)
        {
            ++n;
            --it;
        }
    }
 
    template<class It>
    void do_advance(It& it, typename std::iterator_traits<It>::difference_type n,
                    std::random_access_iterator_tag)
    {
        it += n;
    }
} // namespace detail
 
template<class It, class Distance>
void advance(It& it, Distance n)
{
    detail::do_advance(it, typename std::iterator_traits<It>::difference_type(n),
                       typename std::iterator_traits<It>::iterator_category());
}
Versión constexpr
template<class It, class Distance>
constexpr void advance(It& it, Distance n)
{
    using category = typename std::iterator_traits<It>::iterator_category;
    static_assert(std::is_base_of_v<std::input_iterator_tag, category>);
 
    auto dist = typename std::iterator_traits<It>::difference_type(n);
    if constexpr (std::is_base_of_v<std::random_access_iterator_tag, category>)
        it += dist;
    else
    {
        while (dist > 0)
        {
            --dist;
            ++it;
        }
        if constexpr (std::is_base_of_v<std::bidirectional_iterator_tag, category>)
            while (dist < 0)
            {
                ++dist;
                --it;
            }
    }
}

[editar] Ejemplo

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

Salida:

4 1

[editar] Véase también

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