В чем разница между входными итераторами и итераторами только для чтения? - PullRequest
12 голосов
/ 15 января 2012

В чем разница между входными итераторами и прямыми итераторами только для чтения?

Поскольку последние предназначены только для чтения, они, очевидно, не удовлетворяют требованиям выходных итераторов.И благодаря этому они эффективно вводят итераторы с дополнительными гарантиями (если таковые имеются).Проблема в том, какие дополнительные гарантии?

Я думаю, что прямые итераторы являются многоходовыми, а входные итераторы - нет, я прав?

1 Ответ

21 голосов
/ 15 января 2012

Да, входные итераторы являются однопроходными.Итерировать их можно только один раз, в то время как прямые итераторы являются многопроходными.

С §24.2.3 [input.iterators] p2 (the table), столбец до / после условия ++r:

pre: r является разыменованным.
post: r является разыменованным или r является устаревшим.
post: любые копии предыдущего значения r больше не требуется;быть разыменованным или находиться в области ==.

Последнее постусловие подразумевает, что для a == b, ++a == ++b не обязательно должно быть true.
То жепредложение, абзац 3:

[ Примечание: Для входных итераторов a == b не подразумевает ++ a == ++б .(Равенство не гарантирует свойство подстановки или ссылочную прозрачность.) Алгоритмы на входных итераторах никогда не должны пытаться пройти через один и тот же итератор дважды.Они должны быть однопроходными алгоритмами.[...] Эти алгоритмы могут использоваться с istreams в качестве источника входных данных через шаблон класса istream_iterator. —конечная заметка ]

С §24.2.5 [forward.iterators]

p1 Тип класса или указателя X удовлетворяет требованиям прямого итератора, если

  • [...]
  • объекты типа X предлагают многопроходную гарантию, описанную ниже.

p3 Два разыменовываемых итератора a иb типа X предлагает многопроходную гарантию , если:

  • a == b подразумевает ++a == ++b и
  • X - указатель типаили выражение (void)++X(a), *a эквивалентно выражению *a.
...