Is there more beyond advance takes negative numbers?
4 Answers
- modifies its argument
 - returns nothing
 - works on input iterators or better (or bi-directional iterators if a negative distance is given)
 
- leaves its argument unmodified
 - returns a copy of the argument, advanced by the specified amount
 - works on forward iterators or better (or bi-directional iterators if a negative distance is given))
 
- 13,850
 - 9
 - 56
 - 64
 
- 101,917
 - 9
 - 204
 - 274
 
- 
                    I don't suppose you happen to know why they made it UB to use `next` on an input iterator that's not a forward iterator, even though the defined effect of `next` is guaranteed to work on an input iterator? – Steve Jessop Feb 22 '13 at 06:21
 - 
                    @HowardHinnant: gah, thanks. So basically if you're working with an InputIterator then you should just use `++` (or `advance`, to protect yourself from the devastating convenience of one-liners involving `next`), or write your own `my_next` that quite possibly is identical to your implementation's `std::next`, maybe with a traits assertion removed. It occurs to me that on the same argument, InputIterator shouldn't require `operator++(int)`. Way too late to fix that now, I suppose. – Steve Jessop Feb 22 '13 at 16:09
 - 
                    6If I had a time machine I would take away InputIterator's copy constructor and make it move-only. I think that would make them much safer and easier to reason about. – Howard Hinnant Feb 22 '13 at 18:59
 - 
                    2The extra constraint on `std::next` was backed out by http://cplusplus.github.io/LWG/lwg-defects.html#2353 – T.C. May 13 '16 at 05:23
 
Perhaps the biggest practical difference is that std::next() is only available from C++11.
std::next() will advance by one by default, whereas std::advance() requires a distance.
And then there are the return values:
std::advance(): (none) (the iterator passed in is modified)std::next(): The n th successor.
std::next() takes negative numbers just like std::advance, and in that case requires that the iterator must be bidirectional. std::prev() would be more readable when the intent is specifically to move backwards.
- 136,902
 - 23
 - 188
 - 247
 
- 
                    2`next` doesn't only move forwards, it's like `advance` in that respect. Given the existence of `prev` it might be strange to write `next(it, -1)`, with a negated literal. But for iterators of the right categories it's fine for example to write `next(it, distance(it2, it3))` even if `it2 > it3`. – Steve Jessop Feb 22 '13 at 06:17
 - 
                    1@SteveJessop: Thanks for the edit and for preserving the emphasis on readability. – johnsyweb Feb 26 '13 at 22:59
 - 
                    
 - 
                    Thanks @John. The answer was correct when I wrote it nine years ago. – johnsyweb Feb 25 '22 at 09:47
 
std::advance
The function advance() increments the position of an iterator passed as the argument. Thus, the function lets the iterator step forward (or backward) more than one element:
#include <iterator>
void advance (InputIterator& pos, Dist n)
- Lets the input iterator pos step n elements forward (or backward).
 - For bidirectional and random-access iterators, n may be negative to step backward.
 - Dist is a template type. Normally, it must be an integral type because operations such as <, ++, --, and comparisons with 0 are called.
 - Note that advance() does not check whether it crosses the end() of a sequence (it can’t check because iterators in general do not know the containers on which they operate). Thus, calling this function might result in undefined behavior because calling operator ++ for the end of a sequence is not defined.
 
std::next(and std::prev new in C++11)
#include <iterator>
ForwardIterator next (ForwardIterator pos)
ForwardIterator next (ForwardIterator pos, Dist n)
- Yields the position the forward iterator pos would have if moved forward 1 or n positions.
 - For bidirectional and random-access iterators, n may be negative to yield previous ositions.
 - Dist is type std::iterator_traits::difference_type.
 - Calls advance(pos,n) for an internal temporary object.
 - Note that next() does not check whether it crosses the end() of a sequence. Thus, it is up to the caller to ensure that the result is valid.
 
cite from The C++ Standard Library Second Edition
- 44,644
 - 9
 - 83
 - 100
 
They're pretty much the same, except that std::next returns a copy and std::advance modifies its argument. Note that the standard requires std::next to behave like std::advance: 
24.4.4 Iterator operations [iterator.operations]
template <class InputIterator, class Distance> void advance(InputIterator& i [remark: reference], Distance n);2. Requires: n shall be negative only for bidirectional and random access iterators
3. Effects: Increments (or decrements for negative n) iterator reference i by n.
[...]template <class ForwardIterator> ForwardIterator next(ForwardIterator x, [remark: copy] typename std::iterator_traits<ForwardIterator>::difference_type n = 1);6. Effects: Equivalent to
advance(x, n); return x;
Note that both actually support negative values if the iterator is an input iterator. Also note that std::next requires the iterator to meet the conditions of an ForwardIterator, while std::advance only needs an Input Iterator (if you don't use negative distances).
- 103,620
 - 13
 - 194
 - 236