簡體   English   中英

矢量迭代器擦除條件上的兩個元素

[英]Vector Iterator erase two elements on condition

我正在嘗試從某個向量中刪除2個元素,如果滿足某些條件的話。 我可以成功刪除單個元素而不會出現“矢量迭代器不可解除錯誤”錯誤,我知道這個問題是由於同時刪除了兩個元素引起的,這些元素與迭代器混淆但不確定刪除多個元素的正確方法元素一下子。

vector<SomeObj*> objs;

vector<SomeObj*>::iterator it = objs.begin();
while (it != objs.end())
{
    vector<SomeObj*>::iterator it2 = objs.begin();
    bool deleted = 0;

    while (it2 != objs.end())
    {
        if ((*it)->somecondition(**it2))
        {
            delete *it2;
            *it2 = NULL;
            it = objs.erase(it2);

            delete *it;
            *it = NULL;
            it = objs.erase(it); //Will error here due to invalidating the iterator

            deleted = 1;
            break;
        }
        ++it2;
    }

    if (!deleted)
        ++it;
}

問題是第一次調用erase()可能會使另一個迭代器無效。 有關在各種容器中失效的內容的快速摘要,請參閱此文章 我想說最簡單的解決方案是首先遍歷容器並標記要刪除的條目,但不要刪除它們,然后在第二次掃描中擦除所有標記的內容。 出於性能原因,在第二次掃描中,您應該使用std :: remove_if或使用反向迭代器。

如果要改變容器,使用嵌套迭代器是很棘手的。

我已經整理了一些樣本代碼,可以滿足您的需求。 我正在做的是通過將要刪除的元素設置為nullptr來延遲刪除,然后在循環中遇到它們時刪除它們。

#include <iostream>
#include <vector>

class Example
{
public:
    Example(int size) : size(size) {}

    bool somecondition(const Example& other) const
    {
        return size == other.size;
    }

    int size;
};

int main()
{
    std::vector<Example*> vec;

    vec.push_back(new Example(1));
    vec.push_back(new Example(2));
    vec.push_back(new Example(3));
    vec.push_back(new Example(2));

    for (auto it1 = vec.begin(); it1 != vec.end();)
    {
        if (!*it1)
        {
            it1 = vec.erase(it1);
            continue;
        }

        for (auto it2 = vec.begin(); it2 != vec.end(); ++it2)
        {
            if (!*it2)
            {
                vec.erase(it2);

                // we need to start the outer loop again since we've invalidated its iterator
                it1 = vec.begin();
                break;
            }

            if (it1 != it2 && (*it1)->somecondition(**it2))
            {
                delete *it1;
                *it1 = nullptr;

                delete *it2;
                *it2 = nullptr;

                break;
            }
        }

        ++it1;
    }

    for (auto example : vec)
    {
        std::cout << example->size << std::endl;
    }

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM