19

问候,

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

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

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

将 copy() 函数替换为对 push_back() 的调用按预期工作。

我在这里想念什么?

谢谢你的帮助。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: 
4

5 回答 5

35

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

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 都应替换为基于范围的成员函数。我建议你拿起一份,它是一个很好的参考!

于 2009-07-14T22:58:04.433 回答
27

如其他答案和评论中所述,您应该为此使用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>

于 2009-07-14T23:14:13.933 回答
20

为什么不:vec2 = vec1;

于 2009-07-14T22:59:59.857 回答
4

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

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

(见std::vector::insert

于 2013-01-24T10:47:56.877 回答
3

将保留更改为 resize():

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

我相信这是您需要的解决方案。

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

于 2009-07-14T22:58:55.350 回答