我有两个载体
vector<int> vint;
vector<vector<int>::iterator> viter;
删除vint
中迭代器所在的viter
中的所有元素的最佳方法是什么?目前,我的工作方式暂时转移到list
编辑:(更多背景)
这是我目前的代码。我希望我可以避免移动到列表并返回到载体
void foo(std::vector<Blah>& bvec)
{
std::list<Blah> blist;
std::move(bvec.begin(), bvec.end(), std::back_inserter(blist));
bvec.clear();
std::vector<std::list<Blah>::iterator> selectedElements;
{
//Critical section which holds a mutex. Should be as fast as possible
for(auto it = blist.begin(), it_end= blist.end(); it != it_end; ++it)
{
if(shouldElementBeRemoved(*it))
selectedElements.push_back(it);
}
}
for(auto& it: selectedElements)
{
if(shouldElementReallyBeRemoved(*it))
blist.erase(it);
}
std::move(blist.begin(), blist.end(), std::back_inserter(bvec));
}
如果我可以直接从矢量中删除,可以在没有列表的情况下进行简化。
void foo(std::vector<Blah>& bvec)
{
std::vector<std::vector<Blah>::iterator> selectedElements;
{
//Critical section which holds a mutex. Should be as fast as possible
for(auto it = bvec.begin(), it_end= bvec.end(); it != it_end; ++it)
{
if(shouldElementBeRemoved(*it))
selectedElements.push_back(it);
}
}
for(auto& it: selectedElements)
{
if(shouldElementReallyBeRemoved(*it))
// bvect.erase(it); //Not safe!
}
}
答案 0 :(得分:2)
这对我来说似乎做对了:
#include <algorithm>
for (auto current = vint.end();
current >= vint.begin();) {
current--;
if (any_of(
viter.begin(),
viter.end(),
[current](std::vector<int>::iterator it) {
return current == it;
})) {
vint.erase(current);
}
}
使用any_of
允许迭代器向量未排序。
答案 1 :(得分:2)
你应该可以使用你的第二个片段进行一些小修改 - 而不是向前方向迭代selectedElements
,然后向后移动。然后,对bvec.erase
的调用永远不会使保留在selectedElements
中的任何迭代器失效。
void foo(std::vector<Blah>& bvec)
{
std::vector<std::vector<Blah>::iterator> selectedElements;
selectedElements.reserve(bvec.size()); // avoid growing the vector while you hold a mutex lock
{
//Critical section which holds a mutex. Should be as fast as possible
for(auto it = bvec.begin(), it_end= bvec.end(); it != it_end; ++it)
{
if(shouldElementBeRemoved(*it))
selectedElements.push_back(it);
}
}
for(auto first = selectedElements.rbegin(),
last = selectedElements.rend();
first != last;
++first)
{
if(shouldElementReallyBeRemoved(**first))
bvec.erase(*first);
}
}
答案 2 :(得分:1)
也许这适合您的情况:
struct Blah
{
bool deleted = false; // add a special field
// other data
};
void foo(std::vector<Blah>& bvec)
{
{
//Critical section which holds a mutex. Should be as fast as possible
// mark them quickly
for(auto& b: bvec)
if(shouldElementBeRemoved(b))
b.deleted = true;
}
// remove them slowly
for(auto i = bvec.begin(); i != bvec.end();)
{
if(i->deleted && shouldElementReallyBeRemoved(*i))
i = bvec.erase(i);
else
{
i->deleted = false;
++i;
}
}
}