What's the difference between std::advance and std::next?

C++C++11Std

C++ Problem Overview


Is there more beyond advance takes negative numbers?

C++ Solutions


Solution 1 - C++

std::advance

  • modifies its argument
  • returns nothing
  • works on input iterators or better (or bi-directional iterators if a negative distance is given)

std::next

  • 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))

Solution 2 - C++

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::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.

Solution 3 - C++

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

Solution 4 - C++

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 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 > ForwardIterator next(ForwardIterator x, [remark: copy] typename std::iterator_traits::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).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTavisonView Question on Stackoverflow
Solution 1 - C++Benjamin LindleyView Answer on Stackoverflow
Solution 2 - C++johnsywebView Answer on Stackoverflow
Solution 3 - C++billzView Answer on Stackoverflow
Solution 4 - C++ZetaView Answer on Stackoverflow