Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
396 views
in Technique[技术] by (71.8m points)

c++ - STL vector reserve() and copy()

Greetings,

I am trying to perform a copy from one vector (vec1) to another vector (vec2) using the following 2 abbreviated lines of code (full test app follows):

vec2.reserve( vec1.size() );
copy(vec1.begin(), vec1.end(), vec2.begin());

While the call to vec2 sets the capacity of vector vec2, the copying of data to vec2 seems to not fill in the values from vec1 to vec2.

Replacing the copy() function with calls to push_back() works as expected.

What am I missing here?

Thanks for your help. vectest.cpp test program followed by resulting output follows.

Compiler: gcc 3.4.4 on cygwin.

Nat

/**
 * vectest.cpp
 */

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> vec1;
    vector<int> vec2;

    vec1.push_back(1);
    vec1.push_back(2);
    vec1.push_back(3);
    vec1.push_back(4);
    vec1.push_back(5);
    vec1.push_back(6);
    vec1.push_back(7);

    vec2.reserve( vec1.size() );
    copy(vec1.begin(), vec1.end(), vec2.begin());

    cout << "vec1.size()     = " << vec1.size() << endl;
    cout << "vec1.capacity() = " << vec1.capacity() << endl;

    cout << "vec1: ";
    for( vector<int>::const_iterator iter = vec1.begin(); iter < vec1.end(); ++iter ) {
        cout << *iter << " ";
    }
    cout << endl;

    cout << "vec2.size()     = " << vec2.size() << endl;
    cout << "vec2.capacity() = " << vec2.capacity() << endl;
    cout << "vec2: ";
    for( vector<int>::const_iterator iter = vec2.begin(); iter < vec2.end(); ++iter ) {
        cout << *iter << endl;
    }

    cout << endl;
}

output:

vec1.size()     = 7
vec1.capacity() = 8
vec1: 1 2 3 4 5 6 7 
vec2.size()     = 0
vec2.capacity() = 7
vec2: 
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If the vectors are of the same type, use copy construction or copy assignment:

vec2(vec1);
vec2 = vec1;

If the vectors aren't the exact same (maybe a different allocator or something, or vec1 is a deque), what you really want is the range-based constructor or range-based assign:

vec2(vec1.begin(), vec1.end()); // range-based constructor

vec2.assign(vec1.begin(), vec1.end()); // range-based assignment

If you insist on doing it with std::copy, the proper method is:

copy(vec1.begin(), vec1.end(), back_inserter(vec2));

Since reserving the space does not make it assignable. copy works by assigning each element to its new value. So vec2.size() needs to be at least as large as vec1.size() in your case. Calling reserve doesn't actually change a vector's size, just its capacity.

In the book Effective STL, Scott Meyers argues that nearly all uses of std::copy for insertion should be replaced with range-based member functions. I suggest you pick up a copy, it's a great reference!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...