Currently, std::advance
is designed like this:
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
However, I frequently find myself want something like:
template< class InputIt, class Distance >
InputIt advance( InputIt it, Distance n );
So, what is the rationale behind the current design? Is this for some performance consideration? Note that std::next
and std::prev
do return the resulting iterator.
std::advance in C++. std::advance advances the iterator ‘it’ by n element positions. Syntax : template void advance (InputIterator& it, Distance n); it : Iterator to be advanced n : Number of element positions to advance. This shall only be negative for random-access and bidirectional iterators.
If n is negative, the iterator is decremented. In this case, InputIt must meet the requirements of LegacyBidirectionalIterator, otherwise the behavior is undefined. - InputIt must meet the requirements of LegacyInputIterator . 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++ .
There is no technical reason preventing it to return a reference to the input value, and any reasonable compiler should be able to optimize the return value out if it's not used. So they could have done it that way if they wanted to.
I think their choice makes sense from an API design point of view though - std::prev
and std::next
take an iterator and return a different iterator pointing to the previous or next element, respectively, without modifying the input.
std::advance
on the other hand modifies the input. If it returned a reference to the input iterator, it might be confused for a function that returns a copy without modifying the input in-place. That could potentially be dangerous.
Note that std::advance
works with InputIterator
s, which includes iterators where iteration has side effects (things such as iterators that read from streams), but std::prev
and std::next
only work with ForwardIterator
s, which do not have side effects.
So returning a separate value (like std::prev
and std::next
) would be a bad idea - you'd end up with two iterators on the same stream, which may affect each other adversely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With