Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is *it++ valid for output iterators?

In example code, I often see code such as *it++ for output iterators. The expression *it++ makes a copy of it, increments it, and then returns the copy which is finally dereferenced. As I understand it, making a copy of an output iterator invalidates the source. But then the increment of it that is performed after creating the copy would be illegal, right? Is my understanding of output iterators flawed?

like image 406
fredoverflow Avatar asked Oct 22 '10 22:10

fredoverflow


People also ask

What is an output iterator?

An Output Iterator is a type that provides a mechanism for storing (but not necessarily accessing) a sequence of values.

Are iterators a pointer?

An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container. They can be visualised as something similar to a pointer pointing to some location and we can access content at that particular location using them.

What are three main kinds of iterators?

There are three main kinds of input iterators: ordinary pointers, container iterators, and input streams iterators.

What are iterators iterators are used to?

Iterators are one of the four pillars of the Standard Template Library or STL in C++. An iterator is used to point to the memory address of the STL container classes.


2 Answers

The standard requires that *r++ = t work for output iterators (24.1.2). If it doesn't work, it's not an output iterator by the standard's definition.

It is up to the iterator implementation to make sure such statements work correctly under the hood.

The reason that you shouldn't keep multiple copies of an output iterator is that it has single pass semantics. The iterator can only be dereferenced once at each value (i.e. it has to be incremented between each dereference operation). Once an iterator is dereferenced, a copy of it cannot be.

This is why *r++ = t works. A copy is made of the original iterator, the original iterator is dereferenced and the copy is incremented. The original iterator will never be used again, and the copy no longer references the same value.

like image 56
Dingo Avatar answered Oct 02 '22 18:10

Dingo


The expression *it++ does not (have to) make a copy of it, does not increment it, etc. This expression is valid only for convenience, as it follows the usual semantics. Only operator= does the actual job. For example, in g++ implementation of ostream_iterator, operator*, operator++ and operator++(int) do only one thing: return *this (in other words, nothing!). We could write for example:

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

Instead of: *it++ = 1; *it++ = 2; *it++ = 3; *it++ = 4;

like image 45
rafak Avatar answered Oct 02 '22 18:10

rafak