The
An insert_iterator lets you insert elements in the middle of the sequence, again replacing the meaning of operator=, but this time by automatically calling insert( ) instead of one of the "push" functions. The insert( ) member function requires an iterator indicating the place to insert before, so the insert_iterator requires this iterator in addition to the container object. The shorthand function inserter( ) produces the same object.
The following example shows the use of the different types of inserters:
//: C07:Inserters.cpp
// Different types of iterator inserters
#include
#include
#include
#include
#include
using namespace std;
int a[] = { 1, 3, 5, 7, 11, 13, 17, 19, 23 };
template
void frontInsertion(Cont& ci) {
copy(a, a + sizeof(a)/sizeof(Cont::value_type),
front_inserter(ci));
copy(ci.begin(), ci.end(),
ostream_iterator
cout, " "));
cout << endl;
}
template
void backInsertion(Cont& ci) {
copy(a, a + sizeof(a)/sizeof(Cont::value_type),
back_inserter(ci));
copy(ci.begin(), ci.end(),
ostream_iterator
cout, " "));
cout << endl;
}
template
void midInsertion(Cont& ci) {
typename Cont::iterator it = ci.begin();
it++; it++; it++;
copy(a, a + sizeof(a)/(sizeof(Cont::value_type) * 2),
inserter(ci, it));
copy(ci.begin(), ci.end(),
ostream_iterator
cout, " "));
cout << endl;
}
int main() {
deque
list
vector
// Can't use a front_inserter() with vector
frontInsertion(di);
frontInsertion(li);
di.clear();
li.clear();
backInsertion(vi);
backInsertion(di);
backInsertion(li);
midInsertion(vi);
midInsertion(di);
midInsertion(li);
} ///:~
Since vector does not support push_front( ), it cannot produce a front_insertion_iterator. However, you can see that vector does support the other two types of insertions (even though, as you shall see later, insert( ) is not an efficient operation for vector). Note the use of the nested type Cont::value_type instead of hard-coding int.
More on stream iterators
We introduced the use of the stream iterators ostream_iterator (an output iterator) and istream_iterator (an input iterator) in conjunction with copy( ) in the previous chapter. Remember that an output stream doesn’t have any concept of an "end," since you can always just keep writing more elements. However, an input stream eventually terminates (for example, when you reach the end of a file), so you need a way to represent that. An istream_iterator has two constructors, one that takes an istream and produces the iterator you actually read from, and the other which is the default constructor and produces an object that is the past-the-end sentinel. In the following program this object is named end:
//: C07:StreamIt.cpp
// Iterators for istreams and ostreams
#include
#include
#include
#include
#include
#include "../require.h"
using namespace std;
int main() {
ifstream in("StreamIt.cpp");
assure(in, "StreamIt.cpp");
istream_iterator
ostream_iterator
vector
copy(begin, end, back_inserter(vs));
copy(vs.begin(), vs.end(), out);
*out++ = vs[0];
*out++ = "That's all, folks!";
} ///:~
When in runs out of input (in this case when the end of the file is reached), init becomes equivalent to end, and the copy( ) terminates.
Because out is an ostream_iterator