std::advance
| Definiert in 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 an einen LegacyBidirectionalIterator erfüllen, andernfalls ist das Verhalten undefiniert.
Inhalt |
[bearbeiten] Parameter
| it | - | Der zu verschiebende Iterator |
| n | - | Die Anzahl der Elemente, um die it verschoben werden soll |
| Typanforderungen | ||
-InputIt muss die Anforderungen von LegacyInputIterator erfüllen. | ||
[bearbeiten] Rückgabewert
(keine)
[bearbeiten] Komplexität
Linear.
Wenn InputIt zusätzlich die Anforderungen von LegacyRandomAccessIterator erfüllt, ist die Komplexität konstant.
[bearbeiten] Hinweise
Das Verhalten ist undefiniert, wenn die angegebene Sequenz von Inkrementierungen oder Dekrementierungen erfordert, dass ein nicht inkrementierbarer Iterator (wie der past-the-end-Iterator) inkrementiert wird, oder dass ein nicht dekrementierbarer Iterator (wie der vorderste Iterator oder ein singulärer Iterator) dekrementiert wird.
[bearbeiten] 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; } } } |
[bearbeiten] 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
[bearbeiten] Siehe auch
| (C++11) |
inkrementiert einen Iterator (Funktionsvorlage) |
| (C++11) |
dekrementiert einen Iterator (Funktionsvorlage) |
| gibt die Distanz zwischen zwei Iteratoren zurück (Funktionsvorlage) | |
| (C++20) |
bewegt einen Iterator um die angegebene Distanz vorwärts oder zu einer gegebenen Grenze (Algorithmus-Funktionsobjekt) |