c++ - 给定迭代器列表,如何从 vector 中删除元素?

标签 c++ vector c++14

我有一个 int vector 和一个映射,其中包含一些指向该 vector 的迭代器作为值。我需要从 map 中删除键,以及值指向的 vector 元素。我的代码看起来像这样:

using RenderData = int;
using Element = std::string;

struct Ref {
    std::vector<RenderData>::iterator ref;
    std::function<int()> update;
    bool should_remove;
};

int main() {
    std::vector<RenderData> ints{1, 2, 3, 4, 5, 6, 7, 8, 9};
    std::unordered_map<Element, Ref> elements;

    // Here, I need to remove some elements, and their associated number
}

我实现了一个看起来像 this oneerase_if 函数.

所以我的初始代码是这样的:

erase_if(elements, [&](auto&& element) {
    if (element.second.should_remove) {
        ints.erase(element.second.ref);
        return true;
    }

    return false;
});

显然没有用。删除元素会使其他迭代器指向错误的对象,并且在某些情况下会超出范围。所以我试了一下:

std::vector<std::vector<RenderData>::iterator> to_remove;

erase_if(elements, [&](auto&& element) {
    // condition based on the string content
    if (element.second.should_remove) {
        to_remove.emplace_back(element.second.ref);
        return true;
    }

    return false;
});

// Sort in descending order
std::sort(to_remove.begin(), to_remove.end(), std::greater<>{});

// stuff

for (auto&& it : to_remove) {
    ints.erase(it); // nothing can go wrong right?
}

再一次,我有时会删除错误的元素。

给定存储在某个映射中的迭代器,我可以从 vector 中删除迭代器指向的元素吗?


更新:

在最后一个片段中,我似乎交换了 vector 中的一些元素,从而删除了错误的元素。现在它似乎可以工作了,但我仍然很好奇我们可以使用哪些方法从迭代器列表中删除 vector 中的元素。

最佳答案

使用迭代器版本。 注意:

  1. 迭代器只有在重新分配时才会失效。
  2. 仅用索引替换迭代器不会改变当从 vector 中删除某些值时它们无效的事实。
  3. 使用索引仍然是一种更好的方法,因为它们不会在以后添加更多元素时失效。

方法: 使用不应删除的元素创建 vector 的拷贝

using Element = std::string;
using RenderData = int;
struct Ref {
    std::vector<RenderData>::iterator itr;
    bool should_remove;
};

struct Main {
    std::vector<RenderData> ints;
    std::unordered_map<Element, Ref> elements;
    void remove_stuff(){
        std::vector<RenderData> localCopy;        
        localCopy.swap(ints);
        ints.reserve(localCopy.size());        
        for(auto it = elements.begin(); it != elements.end();) {
            Ref& ref = it->second;
            if(ref.should_remove) {
                it = elements.erase(it);
            } else {
                ints.push_back(std::move(*ref.itr));
                ref.itr = ints.end() - 1;                
                it++;
            }
        }            
    }
};

链接:https://godbolt.org/g/SouZ5E

关于c++ - 给定迭代器列表,如何从 vector 中删除元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48413645/

相关文章:

c++ - vector<char> 优于字符串的好处?

c++ - 带有移动迭代器的独特算法

c++ - objective-c 方法中的 std::vector

c++ - 为什么 std::async 复制它的 const & 参数?

c++ - hash_map< vector<int>, int> 使用查找函数时出错

c++ - C++14 中引入的哪些更改可能会破坏用 C++11 编写的程序?

c++ - 在 C++11 中有零大小的 std::array 的原因吗?

C++ 虚拟继承

用于简单类序列化的 C++/sqlite 包装器?

C++ - 选择最大 "n"值