Accelerated C++ Solution to Exercise 6-4

Exercise 6-4

Correct the program you wrote in the previous exercise to copy from u into v. There are at leaset two possible ways to correct the program. Implement both, and describe the relative advantages and disadvantages of each approach.

Solution

In the previous exercise (See my Solution to Exercise 6-3), it contains the following statement which will crash the system due to attempt to copy additional elements to an empty vector without dynamically growing the vector size up-front (with the like of back_inserter or inserter).

copy(u.begin(), u.end(), v.begin());

As we have already mentioned, we can fix this by using back_inserter or inserter to grow the vector size dynamically.

copy with back_inserter

copy(u.begin(), u.end(), back_inserter(v));

copy with inserter

copy(u.begin(), u.end(), inserter(v, v.begin()));

back_inserter vs inserter

This table summarises my “educational guess” regarding relative advantages and disadvantages of back_inserter and inserter in the context of being used within the copy function.

back_inserter inserter
Advantages Relatively faster element appending (to the back of the base vector) as this is what it is designed to do. capable of inserting elements at the beginning or middle of the base vector.
Disadvantages Not capable of inserting elements at the beginning or middle of the base vector. Relatively slower element appending (to the back of the base vector) as it is designed for flexibility over performance.

The Project

We can perform a test by submitting the following program.

main.cpp

#include <iostream>     // cout, endl
#include <vector>       // vector
#include <algorithm>    // copy

using std::vector;
using std::cout;
using std::endl;

int main()
{
  vector<int> u(10, 100);

  cout << "vector<int> u looks like this:" << endl;
  for (vector<int>::const_iterator i = u.begin(); i != u.end(); ++i)
    cout << (*i) << endl;

  vector<int> v1;
  copy(u.begin(), u.end(), back_inserter(v1));  // use back_inserter to grow v

  cout << "vector<int> v1 looks like this (back_inserter):" << endl;
  for (vector<int>::const_iterator i = v1.begin(); i != v1.end(); ++i)
    cout << (*i) << endl;

  vector<int> v2;
  copy(u.begin(), u.end(), inserter(v2, v2.begin())); // use inserter to grow v2

  cout << "vector<int> v2 looks like this (inserter):" << endl;
  for (vector<int>::const_iterator i = v2.begin(); i != v2.end(); ++i)
    cout << (*i) << endl;
  return 0;
}

Test Program

Submitting the Revised Program gives us the following, which is as expected (and resolved the system crash issue discovered in previous exercise).

vector<int> u looks like this:
100
100
100
100
100
100
100
100
100
100
vector<int> v1 looks like this (back_inserter):
100
100
100
100
100
100
100
100
100
100
vector<int> v2 looks like this (inserter):
100
100
100
100
100
100
100
100
100
100

Reference

Koenig, Andrew & Moo, Barbara E., Accelerated C++, Addison-Wesley, 2000

3 thoughts on “Accelerated C++ Solution to Exercise 6-4”

  1. Your solutions a way to complicated. Try to keep them as simple as possible. There is no reason to output messages in this answer. Makes trying to look through your code, rather slow.

    1. You are probably right on this. Reason I displayed the results was purely for my own benefits – to visualize that all 3 functions (copy, inserter, back_inserter) do indeed produce the same output. These are not mandatory at all for answering the question. So do feel free to remove all the bits and pieces that don’t apply.

  2. Another way to correct the program, which is conceptually different from the two above, is to leave the copy command as it is and add the following line before it:
    v.resize(10);
    The disadvantage is that you have to know in advance how many elements you’ll have to insert.

Leave a reply