# Output Iterator

Category: iterators | Component type: concept

### Description

An Output Iterator is a type that provides a mechanism for storing (but not necessarily accessing) a sequence of values. Output Iterators are in some sense the converse of Input Iterators, but they have a far more restrictive interface: they do not necessarily support member access or equality, and they do not necessarily have either an associated distance type or even a value type [1]. Intuitively, one picture of an Output Iterator is a tape: you can write a value to the current location and you can advance to the next location, but you cannot read values and you cannot back up or rewind.

### Refinement of

Assignable, DefaultConstructible

### Associated types

None. [1]

### Notation

`X` | A type that is a model of Output Iterator
`x`, `y` | Object of type `X`

### Definitions

If `x` is an Output Iterator of type `X`, then the expression `*x = t;` stores the value `t` into `x`. Note that `operator=`, like other C++ functions, may be overloaded; it may, in fact, even be a template function. In general, then, `t` may be any of several different types. A type `T` belongs to the set of value types of `X` if, for an object `t` of type `T`, `*x = t;` is well-defined and does not require performing any non-trivial conversions on `t`. [1]

An Output Iterator may be singular, meaning that the results of most operations, including copying and dereference assignment, are undefined. The only operation that is guaranteed to be supported is assigning a nonsingular iterator to a singular iterator.

An Output Iterator may be dereferenceable, meaning that assignment through it is defined. Dereferenceable iterators are always nonsingular, but nonsingular iterators are not necessarily dereferenceable.

### Valid expressions

Name | Expression | Type requirements | Return type
--- | --- | --- | ---
Default constructor |
    X x;
    X()
Copy constructor | `X(x)` |  | `X`
Copy constructor | `X y(x);` or `X y = x;` |  |
Dereference assignment | `*x = t` | `t` is convertible to a type in the set of value types of `X`. [1] | Result is not used
Preincrement | `++x` |  | `X&`
Postincrement | `(void) x++` |  | `void`
Postincrement and assign | `*x++ = t;` |  | Result is not used

### Expression semantics

Name | Expression | Precondition | Semantics | Postcondition
--- | --- | --- | --- | ---
Default constructor |
    X x;
    X()
|  |  | `x` may be singular
Copy constructor | `X(x)` | `x` is nonsingular |  | `*X(x) = t` is equivalent to `*x = t` [2]
Copy constructor | `X x(y);` or `X x = y;` | `y` is nonsingular |  | `*y = t` is equivalent to `*x = t` [2]
Dereference assignment | `*x = t` | `x` is dereferenceable. If there has been a previous assignment through `x`, then there has been an intervening increment. [3] |  |
Preincrement | `++x` | `x` is dereferenceable. `x` has previously been assigned through. If `x` has previously been incremented, then there has been an intervening assignment through `x` [3] [4] |  | `x` points to the next location into which a value may be stored
Postincrement | `(void) x++` | `x` is dereferenceable. `x` has previously been assigned through. | Equivalent to `(void) ++x` | `x` points to the next location into which a value may be stored
Postincrement and assign | `*x++ = t;` | `x` is dereferenceable. If there has been a previous assignment through `x`, then there has been an intervening increment. [3] [4] | Equivalent to `{*x = t; ++x; }` | `x` points to the next location into which a value may be stored

### Complexity guarantees

The complexity of operations on output iterators is guaranteed to be amortized constant time.

### Invariants

### Models

- ostream_iterator
- insert_iterator
- front_insert_iterator
- back_insert_iterator

### Notes

[1] Other iterator types, including Trivial Iterator and Input Iterator, define the notion of a value type, the type returned when an iterator is dereferenced. This notion does not apply to Output Iterators, however, since the dereference operator (unary `operator*`) does not return a usable value for Output Iterators. The only context in which the dereference operator may be used is assignment through an output iterator: `*x = t`. Although Input Iterators and output iterators are roughly symmetrical concepts, there is an important sense in which accessing and storing values are not symmetrical: for an Input Iterator `operator*` must return a unique type, but, for an Output Iterator, in the expression `*x = t`, there is no reason why `operator=` must take a unique type. [5] Consequently, there need not be any unique "value type" for Output Iterators.

[2] There should be only one active copy of a single Output Iterator at any one time. That is: after creating and using a copy `x` of an Output Iterator `y`, the original output iterator `y` should no longer be used.

[3] Assignment through an Output Iterator `x` is expected to alternate with incrementing `x`, and there must be an assignment through `x` before `x` is ever incremented. Any other order of operations results in undefined behavior. That is: `{*x = t`; ++x; *x = t2; ++x}`is acceptable, but` {*x = t`; ++x; ++x; *x = t2;}` is not.

[4] Note that an Output Iterator need not define comparison for equality. Even if an `operator==` is defined, `x == y` need not imply `++x == ++y`.

[5] If you are implementing an Output Iterator class `X`, one sensible way to define `*x = t` is to define `X::operator*()` to return an object of some private class `X_proxy`, and then to define `X_proxy::operator=`. Note that you may overload `X_proxy::operator=`, or even define it as a member template; this allows assignment of more than one type through Output Iterators of class `X`.

### See also

Trivial Iterator, Input Iterator, Iterator overview

Copyright © 1999 Silicon Graphics, Inc. All Rights Reserved. TrademarkInformation