请使用以下代码段:
// x is a global vector object that holds values of type string as follows, vector<string> x
// x is filled/populated via the function Populate_x(y,z);
Populate_x(y,z);
for (auto i : x)
{
string v = check(i);
Populate_x(v,v);
}
我的问题是,在for循环中调用Populate_x(v,v)时,如何动态更新上述循环范围内的x?我不确定这是否可行。如果没有,我如何重构我的代码以实现这种行为?
非常感谢您的建议。
答案 0 :(得分:3)
基于范围的for
循环等效于:1)获取容器的开始和结束迭代器,2)使用临时迭代器从开始迭代器值迭代到结束迭代器value 3)在每次迭代时,取消引用临时迭代器并将范围循环的变量设置为取消引用的迭代器值。
......或多或少。底线是1)基于范围的for循环获取并使用范围的开始和结束迭代器,2)你声明你的容器是一个向量,并且,如你所知,修改向量将使无效大多数向量内容的迭代器。
对于向量内容的某些修改,某些迭代器不会失效,并且仍然有效。但是,实际上,可以安全地假设,如果某个地方有std::vector::iterator
或std::vector::const_iterator
,修改向量意味着迭代器不再有效。正如我所提到的,并非总是100%正确,但这是一个非常安全的假设。
由于范围迭代获得并使用迭代器到容器,因此在迭代的生命周期中,几乎可以对向量进行范围迭代,并在迭代期间修改向量,这是非启动式。对向量的任何修改都可能导致未定义的行为,对于向量的任何连续迭代。
请注意&#34;修改&#34;基本上是指从向量中插入或移除值;也就是说,修改了矢量本身。修改向量中的值对任何现有迭代器的有效性没有影响,这是安全的。
如果你想迭代一个向量,然后在这个过程中安全地修改向量(修改包括从向量中插入或删除值),你必须自己回答的第一个问题是插入或者是什么删除意味着你的迭代。这是你必须弄明白的事情。例如,如果你的循环当前在向量中的第4个元素上,并且在向量中插入了新的第2个值,因为在向量中插入值会将向量中的所有剩余值向上移动,第4个元素位于向量中。 vector将成为向量中的第5个元素,如果你设法安全地正确执行此操作,则在下一次迭代中,向量中的第5个元素将与之前迭代过的元素相同。这是你想要的吗?首先,你必须自己回答这个问题。
但是,就迭代期间安全地修改向量而言,最简单的方法是避免完全使用迭代器,并使用索引变量:
for (size_t i=0; i<x.size(); ++i)
{
auto v=x[i];
// ...
}
现在,修改向量是完全安全的,然后,你需要弄清楚的是,在向量被修改之后必须发生什么,i
索引变量是否需要无论如何调整。
提出问题,你必须自己回答。
答案 1 :(得分:1)
根据您的描述,我不确定动态更新x的含义。
Populate_x 将新元素添加到<?>
假设您的Populate_x函数尝试push_back
向量x
上的某些元素,那么您就不能这样做。有关详细信息,请参阅this answer
修改循环内的向量会导致未定义的行为,因为修改向量时循环使用的迭代器无效。
如果是这样,如果您想在x
末尾添加多个元素,实际的方法是使用临时vector<string> y;
,push_back
/ emplace_back
元素进入y
,然后在您准备好将y
的所有元素附加到x
后,执行与this类似的操作(在这种情况下v1
是x
您的v2
,y
是您的x.insert(x.end(), make_move_iterator(y.begin()), make_move_iterator(y.end()));
:
ionic run android