Apache C++ Standard Library User's Guide

## 2.4 Insert Iterators

Assignment to the dereferenced value of an output iterator is normally used to overwrite the contents of an existing location. For example, the following invocation of the function `std::copy()` transfers values from one vector to another, although the space for the second vector was already set aside and even initialized by the declaration statement:

    std::vector<int> a(10);
    std::vector<int> b(10);
       // ...
    std::copy(a.begin(), a.end(), b.begin());

Even structures such as lists can be overwritten in this fashion. In the following code, the list named `c` is assumed to have at least ten elements. The initial ten locations in the list will be replaced by the contents of the vector `a`.

    std::list<int> c;
       // ...
    std::copy(a.begin(), a.end(), c.begin());

With structures such as lists and sets, which are dynamically enlarged as new elements are added, it is frequently more appropriate to insert new values into the structure, rather than to overwrite existing locations. A type of adaptor called an insert iterator allows us to use algorithms such as `std::copy()` to insert into the associated container, rather than overwrite elements in the container. The output operations of the iterator are changed into insertions into the associated container. For example, the following code inserts the values of the vector `a` into an initially empty list:

    std::list<int> d;

    std::copy(a.begin(), a.end(), std::front_inserter(d));

There are three forms of insert iterators, all of which can be used to change a copy operation into an insert operation. The iterator generated using `std::front_inserter()`, shown above, inserts values into the front of the container. The iterator generated by `std::back_inserter()` places elements into the back of the container. Both forms can be used with lists and deques, but not with sets or maps. The iterator generated by `std::back_inserter()`, but not by `std::front_inserter()`, can be used with vector.

The third and most general form of insert iterator is that generated by `std::inserter()`, which takes two arguments: a container and an iterator within the container. This form copies elements into the specified location in the container. (For a list, this means elements are copied immediately before the specified location). This form can be used with all the structures for which the previous two forms work, as well as with sets and maps.

The following simple program illustrates the use of all three forms of insert iterators. First, the values 3, 2, and 1 are inserted into the front of an initially empty list. Note that as each value is inserted, it becomes the new front, so that the resultant list is ordered 1, 2, 3. Next, the values 7, 8, and 9 are inserted into the end of the list. Finally, the `find()` operation is used to locate an iterator that denotes the 7 value, and the numbers 4, 5, and 6 are inserted immediately prior. The result is the list of numbers from 1 to 9 in order.

    int main() {
       int threeToOne[]  = {3, 2, 1};
       int fourToSix[]   = {4, 5, 6};
       int sevenToNine[] = {7, 8, 9};

       std::list<int> aList;

       // first insert into the front
       // note that each value becomes new front
       std::copy(threeToOne, threeToOne+3, std::front_inserter(aList));

       // then insert into the back
       std::copy(sevenToNine, sevenToNine+3,
                 std::back_inserter(aList));

       // find the seven, and insert into middle
       std::list<int>::iterator seven =
               std::find(aList.begin(), aList.end(), 7);
       std::copy(fourToSix, fourToSix+3, std::inserter(aList, seven));

       // copy result to output
       std::copy (aList.begin(), aList.end(),
                  std::ostream_iterator<int,char>(std::cout, " "));
       std::cout << std::endl;
    }

Note that there is an important and subtle difference between the iterator created by `std::inserter()` and the iterator created by `std::front_inserter().` The call on `std::inserter()` copies values in sequence, adding each one to the front of a list, whereas `std::front_inserter()` copies values making each value the new front. The result is that `std::front_inserter()` reverses the order of the original sequence, while `std::inserter()` retains the original order.