Concepts / Iterators and Pointers

Iterators and Pointers

An ostream_iterator is created by specifying both the stream it writes to, such as cout, and the type of objects it accepts, such as string.

  • Programming

A Two-Part Message to Predict

You already know that cout sends text to standard output. An ostream_iterator offers a second way to produce the same kind of output. Instead of calling cout << directly on each piece of text, you create an object that stands in for a position in a stream and then assign values to that position. The stream receives the text as a side effect of the assignment.

Before any rules are introduced, read the program below. It uses an ostream_iterator to print a two-part message. Decide what text appears on the screen, paying attention to the spaces and the newline character, because those are the details that most often cause surprises.

python

What do you think happens?

What text appears on the screen when this program runs?

  • Hello, world with a space, then a newline

  • Hello,world with no space, then a newline

  • Hello, and world on two separate lines

Reveal answer
Answer:

Hello,world with no space, then a newline

The iterator does not add a space or a newline on its own. Each assignment writes exactly the characters in its string literal, so "Hello," is followed directly by "world\n". The only newline is the one written inside the second string.

Creating the Iterator

An ostream_iterator is created by giving it two pieces of information: the stream it will write to, and the type of the objects that will be written to that stream. In the program above, the stream is cout and the type is string. The declaration names both pieces in a single statement, so the iterator knows where its output goes and what kind of values it accepts.

ostream_iteratorthe iterator class<string>type of objects acceptedooname of the iterator(cout)target streamparameterized bydeclareswrites to
Which part of the declaration names the output stream, which part names the type of objects accepted, and how they combine into one iterator.

Read the declaration from left to right. The angle-bracket part names the type of object the iterator accepts, here string. The parenthesized part names the stream, here cout. Together they tell the iterator to accept strings and send them to standard output.

Where an Assignment Sends Its Value

The central behavior is this: assigning a value through the dereferenced iterator writes that value to the stream. The expression *oo is the one you assign to. Writing *oo = "Hello," does not store the text in a variable that you can read back later. It sends the text to cout at the moment of the assignment. Think of the assignment as a write operation that happens to use assignment syntax.

"Hello,"value being assigned*oodereferenced iteratorcoutstandard output streamHello,text appears on screenassigned throughwrite toemits
When *oo = "Hello," runs, the value passes through the iterator and ends up in cout as the stream receives it.

Because the write happens at the moment of the assignment, there is no separate step where the text waits inside the iterator to be printed later. Each assignment produces its own write, and the text of each write appears in the order the assignments were executed.

Tracing the Two-Part Program

Now trace the program from the opening section one statement at a time. The diagram below shows the order of the actions and what the console contains after each one.

ooiterator created for coutcoutconsoleHello,console after firstassignmentworldconsole after secondassignmentwrites 1: Hello,++oo, then writes 2: worldnewline ends the line
In what order do the writes happen as each statement executes, and what text appears on the console after each one?
Worked example

Predicting the two-part program line by line

Predict the exact console output of the program that creates oo for cout, assigns "Hello,", increments oo, and assigns "world\n".

  1. 1
    Line 1: create the iterator

    ostream_iterator<string> oo(cout) names cout as the target and string as the accepted type. Nothing is printed yet, because no value has been assigned.

  2. 2
    Line 2: first assignment

    *oo = "Hello," writes the characters H e l l o comma to cout at this moment. The string literal contains no space and no newline, so none is written.

  3. 3
    Line 3: increment

    ++oo advances the iterator to its next position. It does not write any characters, so the console is unchanged.

  4. 4
    Line 4: second assignment

    *oo = "world\n" writes world followed by the newline character, which is the only newline in the program.

  5. 5
    Combined result

    The two writes arrive in order with nothing between them, so the console shows Hello,world and then moves to a new line.

Result

Hello,world followed by a newline. The space that many readers expect after the comma is absent.

The increment deserves a closer look. The program contains ++oo between the two assignments. The source material explains that this increment mimics writing into an array through a pointer. In that familiar pattern, you write to one element, move the pointer forward to the next element, and write again. The ostream_iterator follows the same rhythm: each assignment is a write, and the increment moves the iterator on before the next write. The increment is not a second output operation. Only the assignments through *oo put text into the stream.

Mistakes That Make Output Diverge

Most ostream_iterator programs that produce unexpected output do so for one of two reasons. The first is miscounting spaces inside string literals. The second is assuming a newline is added automatically when the source does not contain \n. Compare what the programmer expected with what each assignment actually writes.

ExpectedHello, world then newlineHello, worldspace after commaActualHello,world then newlineHello,worldno space after commaexpectswrites
How does the text each assignment actually writes differ from the text the programmer expected it to write?
  • Common mistake

    Assuming a space appears between two assigned strings

    What it looks like
    *oo = "Hello,"; ++oo; *oo = "world\n";
    Why it fails

    The iterator writes exactly the characters in each literal. It does not insert separators between writes.

    Do this instead

    Put the space inside one of the literals, for example "Hello, ", if the space is needed.

  • Common mistake

    Assuming a newline is added automatically after each assignment

    What it looks like

    *oo = "Hello,"; expecting the cursor to move to the next line

    Why it fails

    No newline is written unless the source contains the \n character in the string being written.

    Do this instead

    Include \n in the literal that should end the line, as the second assignment does.

  • Common mistake

    Thinking ++oo writes something

    What it looks like

    ++oo; expecting a visible character

    Why it fails

    The increment only moves the iterator to its next position. It is the assignment through *oo that writes.

    Do this instead

    Count the writes by counting assignments through the dereferenced iterator.

Predict and Check

MEDIUM

Consider this variation: *oo = "Good"; ++oo; *oo = "morning"; ++oo; *oo = "!\n"; Predict the exact console output, then justify it by naming what each assignment writes and noting that each increment writes nothing.

Hints
  • Write down the exact characters that each literal contains, including any spaces or newlines.
  • Concatenate the writes in the order the assignments run, with nothing inserted between them.
  • Expected result: Goodmorning! followed by a newline.

Key Takeaways

  • An ostream_iterator is created by naming both the target stream, such as cout, and the type of objects it accepts, such as string.
  • Assigning a value through the dereferenced iterator, as in *oo = value, writes that value to the stream at the moment of the assignment rather than storing it.
  • The increment ++oo mimics advancing a pointer through an array; it separates one write from the next and does not produce output by itself.
  • Output diverges from expectations mostly because of spaces missing from string literals or because a newline is assumed when the source does not contain \n.

Related concepts

More concepts starting with I