Uses of Iterators
Just as pointers are used in many different ways in traditional programming, iterators are also used for many different purposes. An iterator can be used to denote a specific value, just as a pointer can be used to reference a specific memory location. A pair of iterators can be used to describe a range of values, just as two pointers can be used to describe a contiguous region of memory. However, the values described by iterators are not necessarily physically in sequence; they are logically in sequence because they derive from the same collection, and the second follows the first in the order in which the collection maintains the elements.
Conventional pointers can sometimes be null, meaning they point at nothing. Iterators, too, may not denote any specific value. Just as it is a logical error to dereference a null pointer, it is an error to dereference an iterator that is not denoting a value.
When two pointers that describe a region in memory are used in a C++ program, it is conventional that the ending pointer is not considered part of the region. For example, an array named x of length 10 is sometimes described as extending from x to x+10, even though the element at x+10 is not part of the array. Instead, the pointer value x+10 is the past-the-end value, the element that is the next value after the end of the described range.
Iterators are used similarly to describe a range. The second value is not considered part of the denoted range. Instead, the second value is a past-the-end element, describing the next value in sequence after the final value of the range. Sometimes, as with pointers to memory, this is an actual value in the collection. Other times it may be a special value, specifically constructed for the purpose. In either case, it is not proper to dereference an iterator that is being used to specify the end of a range.
Just as with conventional pointers, the fundamental operation used to modify an iterator is the increment operator, operator ++. When the increment operator is applied to an iterator that denotes the final value in a sequence, it is changed to the past-the-end value. An iterator j is said to be reachable from an iterator i if, after a finite sequence of applications of the expression ++i, the iterator i becomes equal to j. A random access iterator can also decrement (operator --), and increment and decrement by integral amounts (operator += and operator -=).
Ranges can be used to describe the entire contents of a collection by constructing an iterator to the initial element, and a special ending iterator. Each of the collection classes in the Essential Math Module provide both a begin() iterator and an end() iterator which specify the range for all the data contained in that collection. Ranges can also be used to describe subsequences within a single collection by employing two iterators to specific values. Whenever two iterators are used to describe a range, it is assumed that the second iterator is reachable from the first. Although this expectation is not verified, errors can occur if it is not satisfied.