【发布时间】:2018-07-02 23:26:37
【问题描述】:
我有一个 int 向量和一个映射,其中包含一些指向该向量的迭代器作为值。我需要从地图中删除键,以及值指向的向量元素。我的代码看起来像这样:
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?
}
再一次,我有时会擦除错误的元素。
给定存储在某个地图中的迭代器,我可以从向量中删除迭代器指向的元素吗?
更新:
似乎在上一个 sn-p 中我交换了向量中的一些元素,从而擦除了错误的元素。现在它似乎工作了,但我仍然很好奇我们可以用什么方法从迭代器列表中删除向量中的元素。
【问题讨论】:
-
底线是——不要将迭代器存储到内部向量项。如果调整向量的大小,可能会发生迭代器失效。
-
@PaulMcKenzie 我有一个函数可以在调整大小时将元素从地图重新同步到矢量,所以目前这不是问题。也许有了索引,它可能会更快或更容易做到。尽管您的建议是正确的,但不遵循它会导致我目前生活的痛苦。
-
我有一个函数,可以在调整大小时将元素从地图重新同步到矢量 -- 只有当你能够确定所有位置时,该函数才有效可能会发生失效。我会使用索引,并在处理每个项目时删除元素go backwards in the array of indices that are to be removed, from highest index to lowest index,而不是转发。
-
@PaulMcKenzie 我会使用索引——这是我担心的,那时我可能需要进行一些重构。
-
简答:使用索引。长答案,如果您提供更多上下文,例如这些数据结构是什么以及您想对它们执行哪些操作,那么可能会有更好的选择。