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)
Défini dans l'en-tête <iterator>
template < class InputIt, class Distance >
void advance ( InputIt & it, Distance n ) ;
(jusqu'à C++17)
template < class InputIt, class Distance >
constexpr void advance ( InputIt & it, Distance n ) ;
(depuis C++17)

Incrémente l'itérateur donné it de n éléments.

Si n est négatif, l'itérateur est décrémenté. Dans ce cas, InputIt doit satisfaire aux exigences de LegacyBidirectionalIterator , sinon le comportement est indéfini.

Table des matières

Paramètres

it - itérateur à avancer
n - nombre d'éléments it doit être avancé
Exigences de type
-
InputIt doit satisfaire aux exigences de LegacyInputIterator .

Valeur de retour

(aucun)

Complexité

Linéaire.

Cependant, si InputIt satisfait également aux exigences de LegacyRandomAccessIterator , la complexité est constante.

Notes

Le comportement n'est pas défini si la séquence spécifiée d'incréments ou de décréments nécessiterait qu'un itérateur non incrémentable (tel que l'itérateur de fin) soit incrémenté, ou qu'un itérateur non décrémentable (tel que l'itérateur avant ou l' itérateur singulier ) soit décrémenté.

Implémentation possible

Voir également les implémentations dans libstdc++ et libc++ .


Version non-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());
}
Version 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;
            }
    }
}

Exemple

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

Sortie :

4 1

Voir aussi

(C++11)
incrémente un itérateur
(modèle de fonction)
(C++11)
décrémente un itérateur
(modèle de fonction)
retourne la distance entre deux itérateurs
(modèle de fonction)
avance un itérateur d'une distance donnée ou jusqu'à une limite spécifiée
(objet fonction algorithme)