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.
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.
What do you think happens?
What text appears on the screen when this program runs?
Reveal 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.
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.
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.
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".
- 1Line 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. - 2Line 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.
- 3Line 3: increment
++oo advances the iterator to its next position. It does not write any characters, so the console is unchanged.
- 4Line 4: second assignment
*oo = "world\n" writes world followed by the newline character, which is the only newline in the program.
- 5Combined result
The two writes arrive in order with nothing between them, so the console shows Hello,world and then moves to a new line.
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.
Common mistake Assuming a space appears between two assigned strings
What it looks like*oo = "Hello,"; ++oo; *oo = "world\n";Why it failsThe iterator writes exactly the characters in each literal. It does not insert separators between writes.
Do this insteadPut 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 failsNo newline is written unless the source contains the \n character in the string being written.
Do this insteadInclude \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 failsThe increment only moves the iterator to its next position. It is the assignment through *oo that writes.
Do this insteadCount the writes by counting assignments through the dereferenced iterator.
Predict and Check
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_iteratoris 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.