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