我只想删除基于范围的循环中的指定元素:
vector<int> vec = { 3, 4, 5, 6, 7, 8 };
for (auto & i:vec)
{
if (i>5)
vec.erase(&i);
}
出了什么问题?
答案 0 :(得分:15)
您无法按std::vector
上的值删除元素,并且由于基于范围的循环直接暴露了您的代码没有意义的值(vec.erase(&i)
)。
主要问题是当您擦除元素时std::vector
使其迭代器无效。
因此,基于范围的循环基本上实现为
auto begin = vec.begin();
auto end = vec.end()
for (auto it = begin; it != end; ++it) {
..
}
然后擦除一个值会使it
无效并中断连续的迭代。
如果你真的想在迭代时删除一个元素,你必须正确地更新迭代器:
for (auto it = vec.begin(); it != vec.end(); /* NOTHING */)
{
if ((*it) > 5)
it = vec.erase(it);
else
++it;
}
答案 1 :(得分:11)
从正在迭代的向量中删除元素通常是个坏主意。在你的情况下,你最有可能跳过7.更好的方法是使用std::remove_if
:
mySubscribers
vec.erase(std::remove_if(vec.begin(), vec.end(),
[](const int& i){ return i > 5; }),
vec.end());
将应删除的元素移到容器的末尾,并将迭代器返回到第一个元素。你只需要删除那些元素直到最后。
答案 2 :(得分:4)
这非常简单:不要使用基于范围的循环。这些循环旨在作为顺序迭代容器中所有值的简洁形式。如果您想要更复杂的东西(例如擦除或通常访问迭代器),以明确的方式做到:
for (auto it = begin(vec); it != end(vec);) {
if (*it > 5)
it = vec.erase(it);
else
++it;
}