【发布时间】:2015-04-21 06:05:13
【问题描述】:
我有两个向量
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!
}
}
【问题讨论】:
-
我不清楚您所说的“
vint中的所有元素,其迭代器都存在于viter中” -
这些迭代器实际上是从
vint收集的吗?为什么必须暂时将它们复制到list?我不明白这一点。对vint调用的简单(反向)循环和std::vector::erase()不适合您吗? -
如果第二个向量中的迭代器指向 vint,则不能使用擦除,因为您将使迭代器无效。但是,如果迭代器指向另一个向量擦除将完成这项工作
-
您可以使用来自
vint的迭代器在vint上调用erase(),但您必须小心。erase()使其后面的所有迭代器无效,因此您必须从后面向前擦除 -
如果你有索引而不是迭代器会更好。然后你可以对它们进行排序并先删除较大的。