Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::next does not accept InputIterator?

Tags:

c++

c++11

stl

ISO C++11 24.3:

template <class InputIterator, class Distance>
void advance(InputIterator& i, Distance n);
// ...
template <class ForwardIterator>
ForwardIterator next
(
    ForwardIterator x,
    typename std::iterator_traits<ForwardIterator>::difference_type n = 1
);

Why std::next does not accept InputIterators?

One of legal use cases I am thinking about is:

first = find(next(first, x), last, 11); // ...

I have found appropriate DR:

next/prev return an incremented iterator without changing the value of the original iterator. However, even this may invalidate an InputIterator. A ForwardIterator is required to guarantee the 'multipass' property.

But I don't understand how multipass/invalidation is related to that. Using same multipass/invalidation reasoning, we can even ban std::find for InputIterators:

template<class InputIterator, class T>
InputIterator find(InputIterator first, InputIterator last, const T& value);

There is nothing special about std::next in compare to std::find or std::vector::insert(pos, first, last) which have perfectly legal use cases for InputIterators

Moreover std::next(it, n) can be used in generic code, which operates not only on InputIterators.

like image 238
Evgeny Panasyuk Avatar asked Feb 15 '23 20:02

Evgeny Panasyuk


1 Answers

In effect, input iterators cannot be usefully copied, because once an input iterator is incremented, any copy left lying around is invalidated.

std::next takes an iterator and returns another iterator which has been advanced n times. You can't do that with an input iterator without invalidating the original iterator, which makes std::next pointless. By constrast, std::advance advances the specified iterator n times, which is fine with an input iterator.

std::next is the iterator generalization of operator+(T*, size_t). std::advance is the iterator generalization of operator+=(T*&, size_t). It may well be that std::advance, like operator+=, should return a reference instead of void.

It's true that there is a similar issue with std::find (and related functions); they, too, will invalidate any copy of the specified input iterators. But it is quite possible that the committee found that issue less serious.

like image 174
rici Avatar answered Feb 27 '23 17:02

rici