Partial copy from a std::vector

We have a vector with n elements (let's assume n is even, that is not an issue in any case), we want a second vector containing a copy of just the second half of the first one. How should be do that?

The question is posed in a way that should suggest the usage of the assign() function, member of all the standard sequence container. The alternative solutions are usually less attractive being both less immediate and efficient.

Let's create a couple of vectors with some data in it, and dump their content to standard output (the dump() function is showed in a previous post):

const size_t DATA_SIZE = 6;
int data[DATA_SIZE] = { 41, 35, 75, 71, 19, 11};

std::vector<int> v1(data, data + DATA_SIZE);

std::vector<int> v2(v1.rbegin(), v1.rend());

To do the required job we could take it literally. We clear the output vector, then loop on the input vector, starting from its middle element to the end, adding at the end of the output vector a new element copy of the current input one:

for(std::vector<int>::iterator it = v1.begin() + v1.size() / 2;
it != v1.end(); ++it)

We can easily rewrite it using the standard copy() algorithm, that hides the loop in its belly and uses back_inserter() to allocate memory at the end of the output vector:

std::copy(v1.begin() + v1.size() / 2, v1.end(), std::back_inserter(v2));

A marginally better solution would require us to use the inserter() member function that makes clearer that we are inserting new elements in the vector, and not just copying:

v2.insert(v2.end(), v1.begin() + v1.size() / 2, v1.end());

But the preferred one uses the assign() member function:

v2.assign(v1.begin() + v1.size() / 2, v1.end());

No clear() call is required, since it is done internally by assign() and, most importantly, the complete memory allocation is done by assign() in just one chunck (and for other considerations that you could read in Meyer's book).

I love the Effective C++ books by Scott Meyers. Currently, I'm reading the STL instalment, and this post is based on its Item 5.

No comments:

Post a Comment