我有一个 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 one 的 erase_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 中的元素。
最佳答案
使用迭代器版本。 注意:
- 迭代器只有在重新分配时才会失效。
- 仅用索引替换迭代器不会改变当从 vector 中删除某些值时它们无效的事实。
- 使用索引仍然是一种更好的方法,因为它们不会在以后添加更多元素时失效。
方法: 使用不应删除的元素创建 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++;
}
}
}
};
关于c++ - 给定迭代器列表,如何从 vector 中删除元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48413645/