【问题标题】:How do I correctly copy given range of vector to another vector using std::copy?如何使用 std::copy 将给定的向量范围正确复制到另一个向量?
【发布时间】:2019-03-27 15:47:27
【问题描述】:

我找到了几页关于将矢量范围移动到另一个矢量的内容,但是我正在努力使其工作。

我想将元素从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;

但我在 Visual Studio 中得到 Debug Assertion Failed,vector iterator + offset out of range。请注意,我只是在 Visual Studio 2015 中尝试,最后必须在 C++98 中实现 mbed,这意味着我不能使用 std::next 例如。

【问题讨论】:

  • 请注意,您可以通过自定义 build profile 将 C++11 与 Mbed OS 一起使用,您可以在其中设置 -std=c++11

标签: c++98 mbed


【解决方案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 但目标容器的大小不够大,您最终会写入未分配的内存(缓冲区溢出)。

【讨论】:

  • 不幸的是我不能用正确的大小初始化它。至少现在我知道问题出在哪里,我想我会尝试通过预先设置内存来解决它。
  • @TrybGhost 在这种情况下,只需使用resize()。更新了答案。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2021-08-25
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多