Pradyot
Pradyot

Reputation: 3067

stl insertion iterators

Maybe I am missing something completely obvious, but I can't figure out why one would use back_inserter/front_inserter/inserter, instead of just providing the appropriate iterator from the container interface. And thats my question.

Upvotes: 1

Views: 253

Answers (4)

AnT stands with Russia
AnT stands with Russia

Reputation: 320797

It is all a matter of what you really need. Both kinds of iterators can be used, depending on your intent.

When you use an "ordinary" iterator, it does not create new elements in the container. It simply writes the data into the existing consecutive elements of the container, one after another. It overwrites any data that is already in the container. And if it is allowed to reach the end of the sequence, any further writes make it "fall off the end" and cause undefined behavior. I.e. it crashes.

Inserter iterators, on the other hand, create a new element and insert it at the current position (front, back, somewhere in the middle) every time something is written through them. They never overwrite existing elements, they add new ones.

Upvotes: 0

David Thornley
David Thornley

Reputation: 57076

The iterator points to an element, and doesn't in general know what container it's attached to. (Iterators were based on pointers, and you can't tell from a pointer what data structure it's associated with.)

Adding an element to an STL container changes the description of the container. For example, STL containers have a .size() function, which has to change. Since some metadata has to change, whatever inserts the new element has to know what container it's adding to.

Upvotes: 0

Roger Pate
Roger Pate

Reputation:

Because those call push_back, push_front, and insert which the container's "normal" iterators can't (or, at least, don't).

Example:

int main() {
  using namespace std;
  vector<int> a (3, 42), b;

  copy(a.begin(), a.end(), back_inserter(b));

  copy(b.rbegin(), b.rend(), ostream_iterator<int>(cout, ", "));
  return 0;
}

Upvotes: 4

The main reason is that regular iterators iterate over existing elements in the container, while the *inserter family of iterators actually inserts new elements in the container.

std::vector<int> v(3);  // { 0, 0, 0 }
int array[] = { 1, 2, 3 };
std::copy( array, array+3, std::back_inserter(v) ); // adds 3 elements
   // v = { 0, 0, 0, 1, 2, 3 }
std::copy( array, array+3, v.begin() ); // overwrites 3 elements
   // v = { 1, 2, 3, 1, 2, 3 } 
int array2[] = { 4, 5, 6 };
std::copy( array2, array2+3, std::inserter(v, v.begin()) );
   // v = { 4, 5, 6, 1, 2, 3, 1, 2, 3 }

Upvotes: 2

Related Questions