Namespaces
Variants
Actions

std::advance

From cppreference.com
< cpp‎ | iterator
 
 
Iterator library
Iterator primitives Algorithm concepts and utilities Indirect callable concepts Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Defined in header <iterator>
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
(until C++17)
template< class InputIt, class Distance >
constexpr void advance( InputIt& it, Distance n );
(since C++17)

Increments given iterator it by n elements.

If n is negative, the iterator is decremented. In this case, InputIt must meet the requirements of LegacyBidirectionalIterator, otherwise the behavior is undefined.

[edit] Parameters

it - iterator to be advanced
n - number of elements it should be advanced
Type requirements
-InputIt must meet the requirements of LegacyInputIterator.

[edit] Return value

(none)

[edit] Complexity

Linear.

However, if InputIt additionally meets the requirements of LegacyRandomAccessIterator, complexity is constant.

[edit] Notes

The behavior is undefined if the specified sequence of increments or decrements would require that a non-incrementable iterator (such as the past-the-end iterator) is incremented, or that a non-decrementable iterator (such as the front iterator or the singular iterator) is decremented.

[edit] Possible implementation

See also the implementations in libstdc++ and libc++.


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

[edit] Example

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

Output:

4 1

[edit] See also

(C++11)
increment an iterator
(function template) [edit]
(C++11)
decrement an iterator
(function template) [edit]
returns the distance between two iterators
(function template) [edit]
advances an iterator by given distance or to a given bound
(algorithm function object)[edit]

AltStyle によって変換されたページ (->オリジナル) /