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 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:
vector<int> a(10); vector<int> b(10); ... copy (a.begin(), a.end(), b.begin());
Even structures such as lists can be overwritten in this fashion. The following assumes that the list named c has at least ten elements. The initial ten locations in the list will be replaced by the contents of the vector a.
list<int> c; ... 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 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. The following, for example, inserts the values of the vector a into an initially empty list:
list<int> d; copy (a.begin(), a.end(), 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 front_inserter, shown above, inserts values into the front of the container. The iterator generated by 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. back_inserter, but not front_inserter, can be used with vector.
The third, and most general form, is 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 it is inserted, each value 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.
void main() { int threeToOne [ ] = {3, 2, 1}; int fourToSix [ ] = {4, 5, 6}; int sevenToNine [ ] = {7, 8, 9}; list<int> aList; // first insert into the front // note that each value becomes new front copy (threeToOne, threeToOne+3, front_inserter(aList)); // then insert into the back copy (sevenToNine, sevenToNine+3, back_inserter(aList)); // find the seven, and insert into middle list<int>::iterator seven = find(aList.begin(), aList.end(), 7); copy (fourToSix, fourToSix+3, inserter(aList, seven)); // copy result to output copy (aList.begin(), aList.end(), ostream_iterator<int>(cout, " ")); cout << endl;
}
Observe that there is an important and subtle difference between the iterators created by inserter(aList, aList.begin()) and front_inserter(aList). The call on inserter(aList, aList.begin()) copies values in sequence, adding each one to the front of a list, whereas front_inserter(aList) copies values making each value the new front. The result is that front_inserter(aList) reverses the order of the original sequence, while inserter(aList, aList.begin()) retains the original order.