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)
Definiert im Header <iterator>
template < class InputIt, class Distance >
void advance ( InputIt & it, Distance n ) ;
(bis C++17)
template < class InputIt, class Distance >
constexpr void advance ( InputIt & it, Distance n ) ;
(seit C++17)

Erhöht den gegebenen Iterator it um n Elemente.

Wenn n negativ ist, wird der Iterator dekrementiert. In diesem Fall muss InputIt die Anforderungen eines LegacyBidirectionalIterator erfüllen, andernfalls ist das Verhalten undefiniert.

Inhaltsverzeichnis

Parameter

it - Iterator, der vorgerückt werden soll
n - Anzahl der Elemente, um die it vorgerückt werden soll
Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.

Rückgabewert

(keine)

Komplexität

Linear.

Wenn jedoch InputIt zusätzlich die Anforderungen von LegacyRandomAccessIterator erfüllt, ist die Komplexität konstant.

Hinweise

Das Verhalten ist undefiniert, wenn die angegebene Sequenz von Inkrementen oder Dekrementen erfordern würde, dass ein nicht-inkrementierbarer Iterator (wie der past-the-end-Iterator) inkrementiert wird, oder dass ein nicht-dekrementierbarer Iterator (wie der front-Iterator oder der singular Iterator) dekrementiert wird.

Mögliche Implementierung

Siehe auch die Implementierungen in libstdc++ und libc++ .


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

Beispiel

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

Ausgabe:

4 1

Siehe auch

(C++11)
erhöht einen Iterator
(Funktionstemplate)
(C++11)
verringert einen Iterator
(Funktionstemplate)
gibt den Abstand zwischen zwei Iteratoren zurück
(Funktionstemplate)
bewegt einen Iterator um eine gegebene Distanz oder bis zu einer Grenze
(Algorithmus-Funktionsobjekt)