4

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

なぜsstd::nextを受け入れないInputIteratorのですか?

私が考えている合法的なユースケースの1つは次のとおりです。

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

適切なDRを見つけました:

next/prev元のイテレータの値を変更せずにインクリメントされたイテレータを返します。ただし、これでも無効になる場合がありInputIteratorます。ForwardIterator「マルチパス」プロパティを保証するには、Aが必要です。

しかし、マルチパス/無効化がそれにどのように関連しているかはわかりません。同じマルチパス/無効化の推論を使用して、s を禁止することもできstd::findますInputIterator

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

s の完全に合法的なユースケースと比較std::nextして特別なことは何もありませんstd::findstd::vector::insert(pos, first, last)InputIterator

さらに、sstd::next(it, n)だけでなく、一般的なコードでも使用できますInputIterator

4

1 に答える 1

8

実際には、入力反復子を有効にコピーすることはできません。これは、入力反復子がインクリメントされると、そこに残っているコピーが無効になるためです。

std::nextイテレータを取り、時間を進めた別のイテレータを返しますn。元のイテレータを無効にせずに入力イテレータでそれを行うことはできません。これはstd::next無意味です。対照的にstd::advance、指定された反復子のn回数を進めます。これは、入力反復子で問題ありません。

std::nextの反復子の一般化ですoperator+(T*, size_t)std::advanceの反復子の一般化ですoperator+=(T*&, size_t)std::advanceのようoperator+=に、 は void ではなく参照を返す必要があるかもしれません。

std::find(および関連する機能)にも同様の問題があることは事実です。これらも、指定された入力反復子のコピーを無効にします。しかし、委員会がその問題をそれほど深刻ではないと判断した可能性は十分にあります。

于 2013-10-27T00:17:37.230 に答える