Iterators are a generalization of pointers that allow a C++ program to work with different data structures
(for example, containers and ranges) in a uniform manner.
To be able to construct template algorithms that work correctly and
efficiently on different types of data structures, the library formalizes not just the interfaces but also the
semantics and complexity assumptions of iterators.
An input iterator
supports the expression
resulting in a value of some object type
of the iterator.
An output iterator i
has a non-empty set of types that are
to the iterator;
for each such type T
, the expression *i = o
is valid where o
is a value of type T.
Just as a regular pointer to an array guarantees that there is a pointer value pointing past the last element
of the array, so for any iterator type there is an iterator value that points past the last element of a
Values of an iterator i
for which the expression *i
are called dereferenceable.
The library never assumes that past-the-end values are dereferenceable.
Iterators can also have singular values that are not associated with any
After the declaration of an uninitialized pointer x
(as with int* x;
must always be assumed to have a singular value of a pointer.
— end example
Results of most expressions are undefined for singular values;
the only exceptions are destroying an iterator that holds a singular value,
the assignment of a non-singular value to
an iterator that holds a singular value, and, for iterators that meet the
requirements, using a value-initialized iterator
as the source of a copy or move operation.
This guarantee is not
offered for default-initialization, although the distinction only matters for types
with trivial default constructors such as pointers or aggregates holding pointers.
— end note
In these cases the singular
value is overwritten the same way as any other value.
values are always non-singular.