Namespaces
Variants

std:: advance

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>
template < class InputIt, class Distance >
void advance ( InputIt & it, Distance n ) ;
(hasta C++17)
template < class InputIt, class Distance >
constexpr void advance ( InputIt & it, Distance n ) ;
(desde C++17)

Incrementa el iterador dado it en n elementos.

Si n es negativo, el iterador se decrementa. En este caso, InputIt debe cumplir con los requisitos de LegacyBidirectionalIterator , de lo contrario el comportamiento es indefinido.

Contenidos

Parámetros

it - iterador a ser avanzado
n - número de elementos que it debe ser avanzado
Requisitos de tipo
-
InputIt debe cumplir con los requisitos de LegacyInputIterator .

Valor de retorno

(ninguno)

Complejidad

Lineal.

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

Notas

El comportamiento es indefinido si la secuencia especificada de incrementos o decrementos requiriera que un iterador no incrementable (como el iterador pasado-el-final) sea incrementado, o que un iterador no decrementable (como el iterador frontal o el singular iterador) sea decrementado.

Implementación posible

Consulte 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
(plantilla de función)
(C++11)
decrementa un iterador
(plantilla de función)
devuelve la distancia entre dos iteradores
(plantilla de función)
avanza un iterador una distancia dada o hasta un límite especificado
(objeto función de algoritmo)