如何将向量的第一个元素移动到另一个元素

时间:2016-11-23 23:31:48

标签: c++ vector stl iterator

我有两个相同类型的向量,如下所示:

std::vector<Task*> ToRun;
std::vector<Task*> Completed;

完成Task后,需要自动将ToRun向量容器移动到Completed向量中。

ToRun Vector包含 TaskOne TaskTwo TaskThree ... TaskN

已完成的向量包含 nothing

在第一次循环通过ToRun向量后,两个向量应如下所示:

ToRun向量包含 TaskTwo TaskThree ... TaskN

已完成的向量包含 TaskOne

ToRun向量的第二个循环应如下所示:

ToRun向量包含 TaskThree ... TaskN

已完成的向量包含 TaskOne TaskTwo

我有以下代码,但我收到以下错误:

Vector Moving Error

代码段:

for (auto iter = ToRun.begin(); iter != ToRun.end(); iter++)
{
    (*iter)->dump(os);

    Completed.push_back(std::move(ToRun.front()));
    ToRun.erase(ToRun.begin());
}

我试过看thisthis所以回答我没有运气。从发生的事情来看,我认为迭代器在移动前元素后指向null。

我是否应该尝试将任务从一个容器移动到另一个容器然后remove而不是擦除?

2 个答案:

答案 0 :(得分:1)

在此声明之后

ToRun.erase(ToRun.begin());

迭代器iter无效。

来自C ++标准对方法erase

的描述
  

3效果:在点或之后使迭代器和引用无效   擦除。

答案 1 :(得分:1)

迭代时擦除总是很乱。如果删除当前元素,++如何工作?

而是尝试

while (!ToRun.empty()) // loop until empty
{
    ToRun.front()->dump(os);

    Completed.push_back(std::move(ToRun.front()));
    ToRun.erase(ToRun.begin());
}

或类似的东西

但是当你停下来思考它时,那是很严重的。每个eraseToRun中的其余元素移回一个插槽,添加大量不必要的迭代和复制。

for (auto & run: ToRun) // or old school iterator if you prefer
{
    run->dump(os);
    Completed.push_back(std::move(ToRun.front()));
}
toRun.clear();

clear只执行一次,一次性擦除整个容器。更清洁。只需一次迭代就可以确保调用析构函数,并且不会破坏指针。赢了!

将具有相同的效果(假设这不是多线程的,如果你有严重的并发问题)。

Cheersandhth.-Alf也提出了一点,即ToRun似乎包含指针,std::move不是必需的。所有被移动的都是一个指针,这是微不足道的努力。