| | |
Call signature | | |
| (1) | (since C++20) |
| (2) | (since C++20) |
| (3) | (since C++20) |
| | |
1) Increments given iteratori forn times.
2) Increments given iteratori untili== bound.
3) Increments given iteratori forn times, or untili== bound, whichever comes first.
Ifn is negative, the iterator is decremented. In this case,I
must modelstd::bidirectional_iterator, andS
must be the same type asI
ifbound is provided, otherwise the behavior is undefined.
The function-like entities described on this page arealgorithm function objects (informally known asniebloids), that is:
[edit]Parameters
i | - | iterator to be advanced |
bound | - | sentinel denoting the end of the rangei is an iterator to |
n | - | number of maximal increments ofi |
[edit]Return value
3) The difference betweenn and the actual distancei traversed.
[edit]Complexity
Linear.
However, ifI
additionally modelsstd::random_access_iterator, orS
modelsstd::sized_sentinel_for<I>, orI
andS
modelstd::assignable_from<I&, S>, 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.
[edit]Possible implementation
struct advance_fn{template<std::input_or_output_iterator I>constexprvoid operator()(I& i,std::iter_difference_t<I> n)const{ifconstexpr(std::random_access_iterator<I>) i+= n;else{while(n>0){--n;++i;} ifconstexpr(std::bidirectional_iterator<I>){while(n<0){++n;--i;}}}} template<std::input_or_output_iterator I,std::sentinel_for<I> S>constexprvoid operator()(I& i, S bound)const{ifconstexpr(std::assignable_from<I&, S>) i= std::move(bound);elseifconstexpr(std::sized_sentinel_for<S, I>)(*this)(i, bound- i);elsewhile(i!= bound)++i;} template<std::input_or_output_iterator I,std::sentinel_for<I> S>constexprstd::iter_difference_t<I> operator()(I& i,std::iter_difference_t<I> n, S bound)const{ifconstexpr(std::sized_sentinel_for<S, I>){// std::abs is not constexpr until C++23auto abs=[](conststd::iter_difference_t<I> x){return x<0?-x: x;}; if(constauto dist= abs(n)- abs(bound- i); dist<0){(*this)(i, bound);return-dist;} (*this)(i, n);return0;}else{while(n>0&& i!= bound){--n;++i;} ifconstexpr(std::bidirectional_iterator<I>){while(n<0&& i!= bound){++n;--i;}} return n;}}}; inlineconstexprauto advance= advance_fn(); |
[edit]Example
#include <iostream>#include <iterator>#include <vector> int main(){std::vector<int> v{3,1,4}; auto vi= v.begin(); std::ranges::advance(vi,2);std::cout<<"1) value: "<<*vi<<'\n'<<std::boolalpha; std::ranges::advance(vi, v.end());std::cout<<"2) vi == v.end(): "<<(vi== v.end())<<'\n'; std::ranges::advance(vi,-3);std::cout<<"3) value: "<<*vi<<'\n'; std::cout<<"4) diff: "<< std::ranges::advance(vi,2, v.end())<<", value: "<<*vi<<'\n'; std::cout<<"5) diff: "<< std::ranges::advance(vi,4, v.end())<<", vi == v.end(): "<<(vi== v.end())<<'\n';}
Output:
1) value: 42) vi == v.end(): true3) value: 34) diff: 0, value: 45) diff: 3, vi == v.end(): true
[edit]See also
| increment an iterator by a given distance or to a bound (algorithm function object)[edit] |
| decrement an iterator by a given distance or to a bound (algorithm function object)[edit] |
| returns the distance between an iterator and a sentinel, or between the beginning and end of a range (algorithm function object)[edit] |
| advances an iterator by given distance (function template)[edit] |