我有两个相同类型的向量,如下所示:
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
我有以下代码,但我收到以下错误:
代码段:
for (auto iter = ToRun.begin(); iter != ToRun.end(); iter++)
{
(*iter)->dump(os);
Completed.push_back(std::move(ToRun.front()));
ToRun.erase(ToRun.begin());
}
我试过看this和this所以回答我没有运气。从发生的事情来看,我认为迭代器在移动前元素后指向null。
我是否应该尝试将任务从一个容器移动到另一个容器然后remove
而不是擦除?
答案 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());
}
或类似的东西
但是当你停下来思考它时,那是很严重的。每个erase
将ToRun
中的其余元素移回一个插槽,添加大量不必要的迭代和复制。
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
不是必需的。所有被移动的都是一个指针,这是微不足道的努力。