Professional C__ - Marc Gregoire [196]
Using an iterator to access each element sequentially is often more efficient than indexing the container to retrieve each element individually. This generalization is not true for vectors, but applies to lists, maps, and sets.
Adding and Removing Elements
As you have already read, you can append an element to a vector with the push_back() method. The vector provides a parallel remove method called pop_back().
pop_back() does not return the element that it removed. If you want the element you must first retrieve it with back().
You can also insert elements at any point in the vector with the insert() method, which adds one or more elements to a position specified by an iterator, shifting all subsequent elements down to make room for the new ones. There are three different overloaded forms of insert(): one that inserts a single element, one that inserts n copies of a single element, and one that inserts elements from an iterator range. Recall that the iterator range is half-open, such that it includes the element referred to by the starting iterator but not the one referred to by the ending iterator. C++11 adds two more insert() overloads: one that inserts a single element by moving the given element to the vector using move semantics, and another one that inserts a list of elements into the vector where the list of elements is given as an initializer_list. The initializer_list feature is discussed in Chapter 9.
push_back() and insert() take const references to elements, allocate memory as needed to store the new elements, and store copies of the element arguments. C++11 introduces both a push_back() and an insert() method that use move semantics to move ownership of the object to the vector instead of copying the object.
You can remove elements from any point in the vector with erase() and you can remove all elements with clear(). There are two forms of erase(): single element and range specified by an iterator.
If you want to remove a number of elements that satisfy a certain condition, one solution would be to write a loop iterating over all the elements and erasing every element that matches the condition. However, this solution has quadratic complexity, discussed in Chapter 2, which is very bad for performance. In this case, the quadratic complexity can be avoided by using the remove-erase-idiom, which has a linear complexity. The remove-erase-idiom is discussed in Chapter 13.
Here is a small program that demonstrates the methods for adding and removing elements. It uses a helper function printVector() that prints the contents of the vector to cout, but whose implementation is not shown here because it uses algorithms covered in the next chapters. The example also includes demonstrations of the following versions of insert():
insert(const_iterator pos, const T& x); the value x will be inserted at position pos.
insert(const_iterator pos, size_type n, const T& x); the value x will be inserted n times at position pos.
insert(const_iterator pos, InputIterator first, InputIterator last); the elements in the range first, last are inserted at position pos.
vector vector // Oops, we forgot to add 4. Insert it in the correct place. vectorOne.insert(vectorOne.begin() + 3, 4); // Add elements 6 through 10 to vectorTwo. for (int i = 6; i <= 10; i++) { vectorTwo.push_back(i); } printVector(vectorOne); printVector(vectorTwo); // Add all the elements from vectorTwo to the end of vectorOne. vectorOne.insert(vectorOne.end(), vectorTwo.begin(), vectorTwo.end()); printVector(vectorOne); // Now erase the numbers 2 through 5 in vectorOne. vectorOne.erase(vectorOne.begin() + 1, vectorOne.begin() + 5); printVector(vectorOne); // Clear vectorTwo entirely. vectorTwo.clear(); // And add 10 copies of the value 100. vectorTwo.insert(vectorTwo.begin(), 10, 100); // Decide we only want 9 elements. vectorTwo.pop_back(); printVector(vectorTwo); Code snippet from VectorAddRemove\AddRemove.cpp The output of the