一系列基d for
loop等价于:1)获取容器的开始和结束迭代器,2)使用临时迭代器从开始迭代器值迭代到结束迭代器值3)在每次迭代中,解引用临时迭代器并设置范围循环的变量到解除引用的迭代器值。
......或多或少。底线是1)基于范围的for循环获取并使用范围的开始和结束迭代器,以及2)您声明您的容器是一个向量,并且如您所知,修改向量将会失效大多数迭代器都是向量的内容。
确实,对某些类型的向量内容进行修改后,某些迭代器将不会失效并保持有效。但是,实际上,假设如果你有某个地方有std::vector::iterator
或std::vector::const_iterator
,则修改向量意味着迭代器不再有效。正如我所提到的,并非总是100%正确,但这是一个非常安全的假设。
而且由于范围迭代获取并使用容器的迭代器,因此在迭代的整个生命周期中,它几乎都会对向量执行范围迭代,并在迭代过程中修改向量,这是非启动器。对向量的任何修改都可能导致未定义的行为,对于向量的任何持续迭代。请注意,“修饰”实质上是指插入或去除向量中的值;即矢量本身的修改。在向量中修改值对任何现有迭代器的有效性都没有影响,这是安全的。
如果你想遍历一个向量,然后在这个过程中安全地修改向量(修改包括插入或从向量中删除值),你必须自己回答的第一个问题是插入或删除意味着你的迭代。这是你必须弄清楚自己的事情。例如,如果您的循环当前位于矢量的第4个元素中,并且您在矢量中插入了新的第2个值,因为向矢量中插入一个值会将矢量中的所有剩余值向上移动,向量将成为向量中的第5个元素,如果您设法正确安全地执行此操作,则在下一次迭代中,向量中的第5个元素将与之前迭代的第5个元素相同。这是你想要的吗?首先,你必须回答自己。
但据安全改进迭代过程中的载体,最简单的方法是避免使用迭代器完全和使用索引变量:
for (size_t i=0; i<x.size(); ++i)
{
auto v=x[i];
// ...
}
现在,修改矢量是完全安全的,并且所有你必须弄清楚,那么之后矢量被修改后,i
索引变量是否需要以任何方式进行调整。
和那问题你必须回答自己。
也许更完整的示例会有所帮助,但显然您不需要执行相关范围,因此您应该使用其他解决方案,例如传统for循环,但可能是while循环。没有更完整的样本,很难提供具体的样本代码。 – user34660