STL vector reserve()和copy()

时间:2009-07-14 22:56:48

标签: c++ stl vector stl-algorithm

问候,

我正在尝试使用以下2个缩写代码行(从下面的完整测试应用程序)执行从一个向量(vec1)到另一个向量(vec2)的副本:

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

虽然对vec2的调用设置了向量vec2的容量,但是将数据复制到vec2似乎没有填写从vec1到vec2的值。

通过调用push_back()来替换copy()函数可以正常工作。

我在这里缺少什么?

感谢您的帮助。 vectest.cpp测试程序后跟结果输出。

编译器:关于cygwin的gcc 3.4.4。

纳特

/**
 * 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;
}

输出:

vec1.size()     = 7
vec1.capacity() = 8
vec1: 1 2 3 4 5 6 7 
vec2.size()     = 0
vec2.capacity() = 7
vec2: 

5 个答案:

答案 0 :(得分:32)

如果矢量属于同一类型,请使用复制构造或复制分配:

vec2(vec1);
vec2 = vec1;

如果向量不完全相同(可能是不同的分配器或其他东西,或者vec1是双端队列),那么您真正想要的是基于范围的构造函数或基于范围的赋值:

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

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

如果你坚持用std::copy做,那么正确的方法是:

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

由于保留空间不会使其可分配。 copy通过将每个元素分配给其新值来工作。因此vec2.size()至少需要与vec1.size()一样大。调用reserve实际上并不会改变矢量的大小,只会改变其容量。

Effective STL 一书中,Scott Meyers认为几乎所有用于插入的std :: copy都应该用基于范围的成员函数替换。我建议你拿一份,这是一个很好的参考!

答案 1 :(得分:24)

如其他答案和评论中所述,您应该使用vector的内置功能。但是:

当你reserve()元素时,向量将为(至少?)多个元素分配足够的空间。向量中不存在元素,但可以使用内存。这可能会加快push_back(),因为内存已经分配。

当你resize()向量时,它会为这些元素分配足够的空间, ,但也会将它们添加到向量

因此,如果您将矢量调整为100,则可以访问元素0 - 99,但如果您保留100个元素,则它们尚未插入,只是准备好使用。

你想要的是这样的:

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

std::back_inserter<iterator>

中定义

答案 2 :(得分:19)

为什么不:vec2 = vec1;

答案 3 :(得分:3)

将保留更改为调整大小():

vec2.resize(vec1.size(), '\0');
copy(vec1.begin(), vec1.end(), vec2.begin());

我相信这是您需要的修复。

我不能给你一个很好的描述差异,但基本上reserve()确保你有足够的空间,resize()实际上插入了一些东西。

答案 4 :(得分:3)

在我看来,最简单的方法是使用std :: vector :: insert方法:

v2.insert(v2.end(), v1.begin(), v1.end());

(见http://www.sgi.com/tech/stl/Vector.html