Concepts / Working with Iterators

Working with Iterators

Iterators can be obtained in two ways: directly from a container when you first encounter it, and as the return value of an algorithm.

  • Programming

Why Iterators Need a Starting Point

An iterator is only useful if you can get hold of one. Before you can walk through the elements of a collection, or work with one particular element, you need an iterator that refers to that element. This section answers a single question: where do iterators come from?

The answer is that iterators come from two situations. The first is when you first encounter a container. The second is when you call an algorithm. Keep these two sources in mind as you read, because the rest of this section examines each one in turn.

Getting an Iterator from a Container

The first source is the container itself. When you first encounter a container, you can obtain iterators directly from it. The source gives begin() and end() as its examples of this kind of iterator.

The wording the source uses is precise. These iterators refer to useful elements. The point is not that a container hands you a copy of its contents. Instead, the container hands you iterators that point into it. Any later work you do with those iterators is work on the container's own elements.

element 1first stored elementbegin()marks the startelement 2second stored elementelement 3third stored elementend()marks the end boundaryrefers toboundary after last element
Where do begin() and end() point within the container's elements, and why is end() positioned differently from begin()?

The diagram is a schematic and is not a full specification. The source names begin() and end() as the examples to learn from, and it does not spell out their exact positions. Treat the boundary placement of end() as something to confirm when you study the container's elements in detail. What this section establishes is the shape of the exchange: the container gives you an iterator, and that iterator is what you use next.

Getting an Iterator from an Algorithm

The second source is the return value of an algorithm. The standard algorithm find looks for a value in a sequence. When it succeeds, it returns an iterator to the element it found.

This matters because the result of find is not merely a report that the value exists. It is a position you can use to work with that element. The iterator is the handle you then apply to the element.

Tracing a find Call Step by Step

The trace below uses a generic sequence of four elements and a value you are searching for. The steps describe the successful case that the source explains. The source does not describe what find returns when the value is missing, so this trace does not claim anything about that case.

Callercode that needs the elementfindstandard algorithmSequencecontainer of elements1. search for the value2. scan the elements3. matching element located4. return iterator to found element
What happens step by step when find scans the sequence, and which iterator comes back when the value is found?
Worked example

Locating a value and then working with it

A sequence holds the values 4, 9, 2, 7 in that order. You want to find the value 2 and then work with that particular element.

  1. 1
    Ask find to search

    You give find the sequence and the value 2. find looks for that value in the sequence.

  2. 2
    Scan the elements

    find checks the elements in the sequence. The value 4 does not match, and neither does 9. The value 2 matches at the third position.

  3. 3
    Receive the iterator

    Because the search succeeded, find returns an iterator to the element it found, which is the element with value 2.

  4. 4
    Use the iterator

    You now hold a position that refers to that element. Any work you do through this iterator is work on the element in the sequence itself.

Result

find returned an iterator to the element with value 2, and that iterator is what you use to work with the element next.

Choosing Between the Two Sources

The two sources answer different situations. When you first encounter a container and want to work through its elements, the iterator comes directly from the container. When you call an algorithm such as find to locate a value, the iterator comes back as the algorithm's return value. The table below sets the two sources side by side.

Obtained whenyou first encounter thecontainerObtained whenyou call an algorithmExamplesbegin() and end()Examplesfind
How do the two sources differ in where the iterator comes from and when you encounter each one?

Deciding Which Source Applies

When you face a task, you can predict the source by asking one question: does the task begin with a search for a particular value? If so, the iterator you need is the one an algorithm returns. If the task starts from the container itself, you ask the container for its iterators. The flowchart below turns this into a sequence of decisions.

Searching for avalue?Expect iterator fromalgorithm returnfor example, findAsk the container foran iteratorfor example, begin() orend()yesno
Given a task, should you ask the container for an iterator, or expect one from an algorithm's return value?

What do you think happens?

You have a collection and you need to start at its first element. Which source gives you the iterator?

  • The container, through begin()

  • The return value of find

Reveal answer
Answer:

The container, through begin()

begin() is one of the source's examples of iterators obtained directly from a container. No search for a particular value is involved, so an algorithm's return value is not the source here.

EASY

A program has a list of customer names and needs to work with the entry for the name Dana. Which source of iterators applies, and why? Then describe how you would confirm your answer using the flowchart.

Hints
  • Ask whether the task starts from a search for a particular value.
  • The name Dana is a particular value you are looking for.

Mistakes When Sourcing Iterators

  • Common mistake

    Treating the container's contents as a copy you can work on freely

    Why it fails

    The source says these iterators refer to useful elements, meaning they point into the container. Work done through them is work on the container's own elements.

    Do this instead

    Think of each iterator as a position inside the container, not as an independent copy of the data.

  • Common mistake

    Expecting find to return only a yes or no answer

    Why it fails

    The source states that find returns an iterator to the element it found, which is a position you can act on, not only a report that the value exists.

    Do this instead

    When find succeeds, use the iterator it returns to work with the found element.

  • Common mistake

    Assuming every iterator comes from an algorithm

    Why it fails

    The section names two sources. An iterator obtained by first encountering a container, such as one from begin(), does not come from a search.

    Do this instead

    Ask whether the task starts from a search for a particular value before deciding the source.

Key Takeaways

  • Iterators come from two sources: directly from a container when you first encounter it, and as the return value of an algorithm.
  • begin() and end() are the source's examples of iterators obtained from a container.
  • The standard algorithm find returns an iterator to the element it found when it succeeds, giving you a position to work with rather than only a yes or no answer.
  • To predict the source, ask whether the task starts from a search for a particular value: if so, expect an algorithm's return value; if not, ask the container.

Related concepts

More concepts starting with W