如何使用std :: copy将给定的矢量范围正确复制到另一个矢量?

问题描述 投票:1回答:2

我发现了一些关于将矢量范围移动到另一个矢量的页面,但是我正在努力使其工作。

我想将sourceVect中的元素移动到destVect,将sourceVect[1]sourceVect[1+numToCopy]之间的元素移动到sourceVect的开头。我尝试通过以下方式执行此操作:

vector<int> destVect;
vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
int numToCopy = 7;

vector<int>::iterator itSource = sourceVect.begin();
vector<int>::iterator itSourceEnd = sourceVect.begin();
advance(itSource, 1);
advance(itSourceEnd, 1+numToCopy);

std::copy(itSource, itSourceEnd, destVect.begin());             //copy(first,last,output vector ite)


for (vector<int>::iterator it = destVect.begin(); it != destVect.end(); ++it)
    cout << ' ' << *it;

但我得到Debug Assertion Failed,在Visual Studio中向量迭代器+偏移超出范围。请注意,我只是在Visual Studio 2015中尝试它,它必须在C ++ 98中实现mbed的结尾,这意味着我不能使用std::next

c++98 mbed
2个回答
1
投票

std::copy()不会在目标容器中创建新元素。这意味着您需要创建具有正确大小的destVect

vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
vector<int> destVect(sourceVect.size() - 1);

如果您无法使用正确的大小创建它,请稍后在您知道大小的位置调整大小:

destVect.resize(sourceVect.size() - 1);

您现在可以复制:

copy(sourceVect.begin() + 1, sourceVect.end(), destVect.begin());

但是,您可以创建具有正确内容的destVect。您无需手动复制任何内容:

vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
vector<int> destVect(sourceVect.begin() + 1, sourceVect.end());

这是执行此操作的最快方法,并且(可能更重要的是)它不容易出错。如果你执行std::copy但目标容器的大小不够大,最终会写入未分配的内存(缓冲区溢出)。


1
投票

vector::iterator一直支持+,你不需要nextadvance。最简单的方法是从一对迭代器初始化。

 std::vector<int> sourceVect = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
 std::vector<int>::iterator first = sourceVect.begin() + 1;
 std::vector<int>::iterator last = first + numToCopy;
 std::vector<int> destVect(first, last); // contains 2,3,4,5,6,7,8

如果你不能避免延迟声明destVect到你有适当的初始化器,你可以使用assign

 destVect.assign(first, last); // contains 2,3,4,5,6,7,8 overwriting whatever was there before
© www.soinside.com 2019 - 2024. All rights reserved.