首页 文章

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

提问于
浏览
0

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

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

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

ToRun Vector contains TaskOne TaskTwo TaskThree ... TaskN

Completed Vector contains nothing

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

ToRun vector contains TaskTwo TaskThree ... TaskN

Completed Vector contains TaskOne

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

ToRun vector contains TaskThree ... TaskN

Completed Vector contains 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 SO回答但是我已经移动了前面的元素 .

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

2 回答

  • 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 不是必需的 . 所有被移动的都是一个指针,这是微不足道的努力 .

  • 1

    在此声明之后

    ToRun.erase(ToRun.begin());
    

    迭代器 iter 无效 .

    从C标准的方法描述 erase

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

相关问题