【问题标题】:How to move the first element of a vector to the end of another如何将向量的第一个元素移动到另一个向量的末尾
【发布时间】:2016-11-23 23:31:47
【问题描述】:

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

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

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

ToRun 向量包含 TaskOne TaskTwo TaskThree ... TaskN

完整的向量包含 nothing

ToRun 向量的第一次循环之后,两个向量应如下所示:

ToRun 向量包含 TaskTwo TaskThree ... TaskN

完整的向量包含 TaskOne

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

ToRun 向量包含 TaskThree ... TaskN

完整的向量包含 TaskOne TaskTwo

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

代码sn-p:

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

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

我试过查看thisthis SO 答案,但是我没有运气。从正在发生的事情来看,我认为在我移动了前面的元素之后迭代器指向了 null。

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

【问题讨论】:

  • 为什么是erase?即,ToRun 用于其他而不是这个?
  • @Cheersandhth.-Alf ToRun 只是要执行的特定任务的向量。任务的数量取决于配置文件,因此可能很多,也可能很少。我对 STL 容器和迭代器非常缺乏经验,所以我一直在探索我的选择
  • 好吧,那么就没有必要一次一个地erase每个项目(这是您执行顺序的二次时间)。只需清除最后的向量。或者什么都不做。

标签: c++ vector stl iterator


【解决方案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 不是必需的。被移动的只是一个指针,这是微不足道的。

【讨论】:

  • 这就是我要找的!一个循环结构,但不必担心迭代器。
  • 关于效率,move 对原始指针没有影响,而这里的算法是 O(n^2)。
  • @Cheersandhth.-Alf 这太恶心了。我认为编辑是有序的。谢谢。
  • @SPrashad Cheersandhth.-Alf 的评论提出了一个更好的方法来做到这一点。
【解决方案2】:

这句话之后

ToRun.erase(ToRun.begin());

迭代器iter 无效。

来自 C++ 标准对方法 erase 的描述

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

【讨论】:

    猜你喜欢
    • 2013-08-12
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多