有没有办法在像这样的for循环中使用自动变量时擦除特定元素?
for(auto a: m_Connections)
{
if(something)
{
//Erase this element
}
}
我知道我可以说
for(auto it=m_map.begin() ...
或
for(map<int,int>::iterator it=m_map.begin() ...
并手动递增迭代器(并擦除),但如果我能用更少的代码行完成,我就会更开心。
谢谢!
答案 0 :(得分:6)
你做不到。基于范围的循环使得范围内的简单迭代更简单,但不支持使范围或其使用的迭代器无效的任何内容。当然,即使支持它,也无法在不访问迭代器的情况下有效地擦除元素。
你需要一个老派的循环,按照
的方式for (auto it = container.begin(); it != container.end();) {
if (something) {
it = container.erase(it);
} else {
++it;
}
}
或container.erase()
和std::remove_if
的组合,如果你喜欢那种东西。
答案 1 :(得分:5)
不,没有。基于范围的循环用于访问容器的每个元素一次。
每次从容器中删除元素时,擦除元素处或之后的迭代器都不再有效(并且给定the implementation of the range-based-for这是一个问题)。
如果您需要随意修改容器,则应使用normal for循环(或while
)。
如果要删除谓词返回true
的元素,一个好方法是:
m_Connections.erase(
std::remove_if(m_Connections.begin(),
m_Connections.end(),
[](Type elem) { return predicate(elem); }),
m_Connections.end());
std::remove_if不会将迭代逻辑与谓词混合。
答案 2 :(得分:3)
如果要从容器中擦除元素,则需要迭代器。
并且您无法从元素本身获取迭代器 - 即使您可以,例如使用vector
,基于范围的内部使用的迭代器将在下一步中失效,从而导致未定义的行为点。
所以答案是:不,在它的经典用法中你不能。基于范围的,仅用于方便迭代范围内的所有元素。
答案 3 :(得分:1)
将所有元素推入数组,然后执行弹出操作以删除项