如何在给定迭代器列表的情况下从向量中删除元素
How can I erase elements from a vector given a list of iterator?
我有一个 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
}
我实现了一个看起来像这样的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?
}
再一次,我有时会删除错误的元素。
给定迭代器存储在某个映射中,我可以从向量中删除迭代器指向的元素吗?
更新:
似乎在最后一个片段中,我交换了矢量中的一些元素,从而擦除了错误的元素。现在它似乎有效,但我仍然很好奇我们可以做些什么来从迭代器列表中擦除向量中的元素。
使用迭代器版本。注意:
- 仅当存在重新分配时,迭代器才会失效。
- 只需将迭代器替换为 index 不会改变从向量中删除某些值时它们无效的事实。
- 使用索引仍然是一种更好的方法,因为稍后添加更多元素时它们不会失效。
方法:使用不应删除的元素创建矢量的副本
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
计划 A :你最好用std::list更改std::vector,std::list的迭代器在擦除后不会无效。
计划B:
std::vector<int> newOne;
copy_if(oldOne.begin(), oldPOne.end(), std::back_inserter(newOne), [](){ //to test not in the map ~~ });
oldOne = std::move(newOne)
使用索引而不是迭代器。取代
struct Ref {
std::vector<RenderData>::iterator ref;
std::function<int()> update;
bool should_remove;
};
std::vector< std::vector<RenderData>::iterator> to_remove;
跟
struct Ref {
std::size_t ref;
std::function<int()> update;
bool should_remove;
};
std::vector< std::size_t> to_remove;
然后你用后代排序的好主意就会起作用。通过索引调用ints.erase(ints.begin() + ref)
擦除元素
迭代器的排序是一个错误的想法。矢量迭代器的实现方式是不可预测的。它们的排序顺序与指针/地址/索引的排序顺序相同的可能性非常小。
迭代器擦除( 迭代器 POS (;(至C++11(
迭代器擦除( const_iterator pos (;(自C++11起(
删除位置处的元素。
使擦除点处或之后的迭代器和引用失效,包括 end(( 迭代器。
相关文章:
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 如何在不C++排序的情况下找到给定向量中的第一、第二和第三高值?
- 如何在不复制的情况下将一个向量移动到另一个向量中
- C++数组与向量排序(在我的情况下,向量比数组慢~2.5倍(无优化))
- 在无法访问向量的情况下查找迭代器的末尾
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 我怎样才能在不重复的情况下随机迭代向量的每个元素
- 调整向量大小并检索值,这是否正确或在任何情况下都可能导致段错误?
- 如何在不迭代的情况下从string_view向量创建字符串向量?
- 如何在不以不同方式创建每个向量的情况下制作 2-D 向量列表?
- 如何在不使用标准算法的情况下在排序向量中添加 c 元素?
- 是否可以在不指定类型的情况下从 istringstream 转到向量?
- 在不使用递归的情况下求解所有 2D 字符串向量组合?(C++)
- 如何在不复制的情况下将向量向量从类函数传递到功能
- 如何在<typename> <long> 不更改给定代码的情况下将自定义向量与 STL 向量相互转换?
- 我可以在不循环访问数组/向量的情况下检查数组/向量中的单词吗?
- 如何在使用和无发现的情况下使用和不使用的字符串向量搜索元素
- 您可以在没有列表或向量的情况下循环访问类对象吗?
- 如何在给定迭代器列表的情况下从向量中删除元素
- 为什么在<int> <bool> 以下情况下向量比向量快