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

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

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

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


person Community    schedule 15.01.2012    source источник


Ответы (1)


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

Из §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 == ++b. (Равенство не гарантирует свойства замещения или ссылочной прозрачности.) Алгоритмы для итераторов ввода никогда не должны пытаться пройти через один и тот же итератор дважды. Это должны быть однопроходные алгоритмы. [...] Эти алгоритмы можно использовать с 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.
person Xeo    schedule 15.01.2012
comment
Типичными примерами могут быть итератор потока (однопроходный, итератор ввода) и односвязный список (многопроходный итератор вперед). - person jalf; 15.01.2012
comment
ой, кстати, есть upboat. +1 - person jalf; 15.01.2012