为什么std :: next不接受InputIterator?

时间:2013-10-27 00:12:49

标签: 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
);

为什么std::next不接受InputIterator

我正在考虑的一个合法用例是:

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

我找到了合适的DR

  

next / prev返回递增的迭代器而不更改原始迭代器的值。但是,即使这样也可能使InputIterator无效。需要ForwardIterator来保证'multipass'属性。

但我不明白多通/失效是如何与此相关的。使用相同的多遍/无效推理,我们甚至可以std::find禁止InputIterator

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

std::nextstd::findstd::vector::insert(pos, first, last)相比,InputIterator具有完全合法的使用案例,没有什么特别之处

此外std::next(it, n)可用于通用代码,该代码不仅在InputIterator s上运行。

1 个答案:

答案 0 :(得分:8)

实际上,输入迭代器无法有效复制,因为一旦输入迭代器递增,任何留下的副本都会失效。

std::next接受一个迭代器并返回另一个已经提前n次的迭代器。你不能使用输入迭代器来做到这一点而不会使原始迭代器失效,这会使std::next毫无意义。通过约束,std::advance提前指定的迭代器n次,这对于输入迭代器来说很好。

std::nextoperator+(T*, size_t)的迭代器泛化。 std::advanceoperator+=(T*&, size_t)的迭代器泛化。很可能std::advanceoperator+=一样,应该返回引用而不是void。

std::find(和相关函数)存在类似的问题;它们也会使指定输入迭代器的任何副本无效。但委员会很可能发现问题不那么严重。