Входной итератор может быть прочитан повторно, а выходной итератор может быть записан только один раз - PullRequest
0 голосов
/ 31 января 2019

Я читал Язык программирования C ++ 4-е издание Бьярна Страуструпа.В главе об итераторах (глава 31.1.2) говорится:

Итератор ввода: мы можем выполнять итерацию вперед, используя ++, и читать каждый элемент ( многократно ), используя *.

Выходной итератор: мы можем выполнить итерацию вперед, используя ++, и написать элемент только один раз , используя *.

Я провел много поисков о том, может ли входной итератор бытьчитать только один или несколько раз, например: http://www.cplusplus.com/reference/iterator/InputIterator/ https://www.geeksforgeeks.org/input-iterators-in-cpp/

и большинство предполагает, что входной итератор может быть прочитан только один раз.Но почему автор неоднократно говорит о входном итераторе?Это правильно?И если так, почему входной итератор может быть прочитан повторно, а выходной итератор может быть записан только один раз.Я всегда думал, что входной и выходной итератор полностью противоположны друг другу.

Спасибо всем!

Ответы [ 3 ]

0 голосов
/ 31 января 2019

Цитата Бьярне верна.Если у вас есть входной итератор, вы можете сделать *iterator столько раз, сколько захотите.Если у вас есть выходной итератор, вы можете сделать *iterator только один раз.

Что общего у них обоих, хотя они могут использоваться только в однопроходных алгоритмах.Как только вы увеличиваете входной или выходной итератор, итератор на предыдущую позицию больше не должен быть разыменованным

Это означает, что в

while (iterator != end)
{
    if (*iterator == some_value)
        something = *iterator;
    ++iterator;
}

iterator должен быть входной итератортак как мы разыменовываем его дважды в каждой итерации.С другой стороны,

while (iterator != end)
{
    something = *iterator;
    ++iterator;
}

работает как для входных, так и для выходных итераторов, поскольку мы выполняем только одну разыменование.

0 голосов
/ 31 января 2019

Вы можете читать итератор ввода столько раз, сколько захотите.Это вытекает из требования, что "(void)*a, *a эквивалентно *a" [input.iterators], см. Таблицу.

Вы можете записывать через выходной итератор только один раз.Для *r = o «После этой операции r не обязательно должен быть разыменованным».[output.iterators], см. таблицу.После увеличения r у вас есть новый итератор, и вы можете снова назначить его через него один раз.

Как только вы объедините эти два значения в итератор forward , ограничение на несколько назначений черезтот же итератор уходит.

0 голосов
/ 31 января 2019

Книга верна;и противоречивые источники не являются.Как представляется, не существует правила, запрещающего чтение объекта более одного раза путем косвенного ввода через входной итератор.

Другие источники могут быть сбиты с толку другим аналогичным ограничением, заключающимся в том, что после увеличения входного итератора все копиипредыдущий итератор признан недействительным и, следовательно, больше не может быть перенаправлен.Это ограничение разделяют выходные итераторы.Например:

value = *inputIt;
value = *inputIt; // OK
copyIt = inputIt;
++inputIt;
value = *copyIt;  // Not OK

В книге также верно, что итератор вывода имеет ограничение:

 *outputIt = value;
  ++outputIt;
 *outputIt = value; // OK
 *outputIt = value; // Not OK

Я всегда думал, что итератор ввода и вывода полностью противоположендруг друга.

Многие выходные итераторы также являются входными итераторами, поэтому «противоположность» не совсем описательна.Они частично перекрывают наборы требований.Итератор может удовлетворить оба набора требований.

Если у нас есть * outputIt = 1;тогда * outputIt = 2;Разве мы не назначаем один и тот же * выход дважды?

Да;И это то, что выходные итераторы не обязаны поддерживать.

Рассмотрим, например, выходной итератор, который отправляет пакеты через Интернет.Вы написали пакет, и он был отправлен в Интернет и получен на другой машине.Вы не можете путешествовать во времени и решить, что отправленный пакет является чем-то другим.Вы должны перейти к следующему пакету и отправить его вместо этого.

...