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
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.
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.
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.
thanks.
i think the book wants you to compare the following: (1) the iterator adapter approach with the library algortihm “copy”, and (2) the non-algorithmic approach that is familiar from earlier chapters (i.e. loop through ‘u’ and append elements one at a time to ‘v’). the advantages and disadvantages should revolve around the benefits of using library algorithms for problem solving.
Probably not. This is the code the author has provided: https://github.com/bitsai/book-exercises/blob/master/Accelerated%20C%2B%2B/chapter06/6-4.cpp