Espacios de nombres
Variantes

std::advance

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>
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.

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.

Valor de retorno

(ninguno)

Complejidad

Lineal.

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

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.

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;
            }
    }
}

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

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]