Подтвердить что ты не робот

Каким образом * it ++ допустим для итераторов вывода?

В примере кода я часто вижу код, например *it++ для итераторов вывода. Выражение *it++ делает копию it, увеличивает it, а затем возвращает копию, которая окончательно разыменовывается. Насколько я понимаю, создание копии выходного итератора приводит к недействительности источника. Но тогда приращение it, которое выполняется после создания копии, было бы незаконным, не так ли? Является ли мое понимание выходных итераторов ошибочным?

4b9b3361

Ответ 1

Выражение *it++ не должно (должно) сделать его копию, не увеличивать его и т.д. Это выражение справедливо только для удобства, так как оно следует обычной семантике. Только operator= выполняет фактическое задание. Например, в g++ реализация ostream_iterator, operator*, operator++ и operator++(int) выполняет только одно: return *this (другими словами, ничего!). Мы могли бы написать, например:

it = 1;
it = 2;
*it = 3;
++it = 4;

Вместо *it++ = 1; *it++ = 2; *it++ = 3; *it++ = 4;

Ответ 2

Стандарт требует, чтобы *r++ = t работал для выходных итераторов (24.1.2). Если это не работает, это не выходной итератор стандартным определением.

Это зависит от реализации итератора, чтобы убедиться, что такие выражения корректно работают под капотом.

Причина, по которой вы не должны хранить несколько копий выходного итератора, состоит в том, что она имеет однопроходную семантику. Итератор может быть разыменован только раз в каждом значении (т.е. Он должен увеличиваться между каждой операцией разыменования). Как только итератор разыменован, его копия не может быть.

Вот почему работает *r++ = t. Копия делается из оригинального итератора, исходный итератор разыменовывается, и копия увеличивается. Исходный итератор никогда не будет использоваться снова, и копия больше не ссылается на одно и то же значение.

Ответ 3

Итераторы вывода просто не работают, как обычные итераторы, и их интерфейс указан таким образом, что их можно использовать в указательных выражениях (*it++ = x) с полезными результатами.

Как правило, operator*(), operator++() и operator++(int) все возвращают *this в качестве эталонных и выводных итераторов имеют волшебный operator=, который выполняет ожидаемую операцию вывода. Поскольку вы не можете читать из выходного итератора, тот факт, что operator*() и т.д., Не работает, как и для других итераторов, не имеет значения.

Ответ 4

Глядя на ваш комментарий, кажется, что большая часть путаницы возникает из документации SGI, которая, как я бы сказал, немного вводит в заблуждение в этой точке.

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

Ответ 5

Не является ли итератором только указатель? Приращение, а затем разыменование его просто переходит к следующему элементу.