2016-11-23 84 views
0

结束我已在相同类型的两个矢量,如下所示:如何将一个向量的第一元素移动到另一个

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

Task完成时,它需要被自动从移动ToRun将容器载入Completed载体。

托伦向量包含TaskOne TaskTwo TaskThree ... TaskN

完成向量包含nothing

通过ToRun向量第一环路之后,两种载体应该如下:

托伦载体含有TaskTwo TaskThree ... TaskN

完整载体包含TaskOne

通过ToRun向量执行第二循环应该如下:

托伦载体包含TaskThree ... TaskN

完整载体包含TaskOne TaskTwo

我有下面的代码,但我接收艾尔文以下错误:

Vector Moving Error

代码片段:

​​

我试图寻找thisthis SO回答不过我有没有运气。从发生的事情来看,我认为迭代器在移动front元素之后指向null。

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

+0

为什么“擦除”?也就是说,用于其他**的“ToRun”是什么? –

+0

@ Cheersandhth.-Alf'ToRun'只是执行特定任务的向量。任务的数量取决于配置文件,因此可能会有很多或者一些。我对STL容器和迭代器非常缺乏经验,所以我一直在探索我的选项 – Sean

+0

那么没有必要一次一个“擦除”每个项目(这是您按照顺序执行的二次时间)。最后只需清除矢量。或者什么都不做。 –

回答

1

擦除而迭代总是凌乱的C++标准的描述。如果您擦除当前元素,++如何工作?

而是尝试

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是没有必要的。所有正在移动的东西都是一个指针,而这只是一个小小的努力。

+0

这就是我一直在寻找的!循环结构,但不必担心迭代器。 – Sean

+0

关于效率,'move'对原始指针没有影响,而这里的算法是O(n^2)。 –

+1

@ Cheersandhth.-Alf它很粗糙。我认为编辑是有序的。谢谢。 – user4581301

1

这种说法

ToRun.erase(ToRun.begin()); 

迭代iter后无效。

从方法erase

3 Effects: Invalidates iterators and references at or after the point of the erase.

相关问题