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.
| it | - | iterator to be advanced |
| n | - | number of elements it should be advanced |
| Type requirements | ||
-InputIt must meet the requirements of LegacyInputIterator. |
||
(none).
Linear.
However, if InputIt additionally meets the requirements of LegacyRandomAccessIterator, complexity is constant.
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.
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;
}
}
}
} |
#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
|
(C++11) | increment an iterator (function template) |
|
(C++11) | decrement an iterator (function template) |
| returns the distance between two iterators (function template) |
|
|
(C++20) | advances an iterator by given distance or to a given bound (niebloid) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/iterator/advance