std::advance - cppreference.com

From cppreference.com

Defined in header

<iterator>

template<classInputIt,classDistance>voidadvance(InputIt&it,Distancen);(until C++17)template<classInputIt,classDistance>constexprvoidadvance(InputIt&it,Distancen);(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.

Parameters

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

LegacyInputIterator

. Return value

(none)

Complexity

Linear.

However, if InputIt additionally meets the requirements of

LegacyRandomAccessIterator

, complexity is constant.

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.

Possible implementation

See also the implementations in

libstdc++

and

libc++

.

Non-constexpr version

namespacedetail{template<classIt>voiddo_advance(It&it,typenamestd::iterator_traits<It>::difference_typen,std::input_iterator_tag){while(n>0){--n;++it;}}template<classIt>voiddo_advance(It&it,typenamestd::iterator_traits<It>::difference_typen,std::bidirectional_iterator_tag){while(n>0){--n;++it;}while(n<0){++n;--it;}}template<classIt>voiddo_advance(It&it,typenamestd::iterator_traits<It>::difference_typen,std::random_access_iterator_tag){it+=n;}}// namespace detailtemplate<classIt,classDistance>voidadvance(It&it,Distancen){detail::do_advance(it,typenamestd::iterator_traits<It>::difference_type(n),typenamestd::iterator_traits<It>::iterator_category());}

constexpr version

template<classIt,classDistance>constexprvoidadvance(It&it,Distancen){usingcategory=typenamestd::iterator_traits<It>::iterator_category;static_assert(std::is_base_of_v<std::input_iterator_tag,category>);autodist=typenamestd::iterator_traits<It>::difference_type(n);ifconstexpr(std::is_base_of_v<std::random_access_iterator_tag,category>)it+=dist;else{while(dist>0){--dist;++it;}ifconstexpr(std::is_base_of_v<std::bidirectional_iterator_tag,category>)while(dist<0){++dist;--it;}}}Example

Run this code

#include<iostream>#include<iterator>#include<vector>intmain(){std::vector<int>v{3,1,4};autovi=v.begin();std::advance(vi,2);std::cout<<*vi<<' ';vi=v.end();std::advance(vi,-2);std::cout<<*vi<<'\n';}Output:

4 1 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]

(C++20)

advances an iterator by given distance or to a given bound
(algorithm function object)

[edit]