An inserter is an iterator adaptor (§ 9.6, p. 368) that takes a container and yields an iterator that adds elements to the specified container. When we assign a value through an insert iterator, the iterator calls a container operation to add an element at a specified position in the given container. The operations these iterators support are listed in Table 10.2 (overleaf).
There are three kinds of inserters. Each differs from the others as to where elements are inserted:
• back_inserter
(§ 10.2.2, p. 382) creates an iterator that uses push_back
.
• front_inserter
creates an iterator that uses push_front
.
• inserter
creates an iterator that uses insert
. This function takes a second argument, which must be an iterator into the given container. Elements are inserted ahead of the element denoted by the given iterator.
We can use front_inserter
only if the container has push_front
. Similarly, we can use back_inserter
only if it has push_back
.
It is important to understand that when we call inserter(c, iter)
, we get an iterator that, when used successively, inserts elements ahead of the element originally denoted by iter
. That is, if it
is an iterator generated by inserter
, then an assignment such as
* it = va1;
behaves as
it = c.insert(it, val); // it points to the newly added element
++it; // increment it so that it denotes the same element as before
The iterator generated by front_inserter
behaves quite differently from the one created by inserter
. When we use front_inserter
, elements are always inserted ahead of the then first element in the container. Even if the position we pass to inserter
initially denotes the first element, as soon as we insert an element in front of that element, that element is no longer the one at the beginning of the container:
list<int> 1st = {1,2,3,4};
list<int> lst2, lst3; // empty lists
// after copy completes, 1st2 contains 4 3 2 1
copy(1st.cbegin(), lst.cend(), front_inserter(lst2));
// after copy completes, 1st3 contains 1 2 3 4
copy(1st.cbegin(), lst.cend(), inserter(lst3, lst3.begin()));
When we call front_inserter(c)
, we get an insert iterator that successively calls push_front
. As each element is inserted, it becomes the new first element in c
. Therefore, front_inserter
yields an iterator that reverses the order of the sequence that it inserts; inserter
and back_inserter
don’t.
Exercise 10.26: Explain the differences among the three kinds of insert iterators.
Exercise 10.27: In addition to unique
(§ 10.2.3, p. 384), the library defines function named unique_copy
that takes a third iterator denoting a destination into which to copy the unique elements. Write a program that uses unique_copy
to copy the unique elements from a vector
into an initially empty list
.
Exercise 10.28: Copy a vector
that holds the values from 1
to 9
inclusive, into three other containers. Use an inserter
, a back_inserter
, and a front_inserter
, respectivly to add elements to these containers. Predict how the output sequence varies by the kind of inserter and verify your predictions by running your programs.