如何在 C++ 中动态更新 for 循环的条件?

How to dynamically update the condition of a for loop in C++?

采用以下代码片段:

// 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) 时,如何在上面显示的基于范围的 for 循环中动态更新 x?我不确定这是否可能。如果没有,我如何重构我的代码以实现此行为?

非常感谢您的建议。

根据您的描述,我不确定动态更新 x 是什么意思。

是否Populate_x 向 x 添加 新元素?

假设您的 Populate_x 函数尝试 push_back 向量 x 上的一些元素,那么您不能这样做。有关详细信息,请参阅 this answer

Modifying the vector inside the loop results in undefined behaviour because the iterators used by the loop are invalidated when the vector is modified.

如果是这样,如果你想在x的末尾添加多个元素,一个实用的方法是使用临时的vector<string> y;push_back/emplace_back 元素到 y,然后一旦你准备好将 y 的所有元素附加到 x ,做一些类似于 this 的事情(在这种情况下 v1 是你的 xv2 是你的 y :

x.insert(x.end(), make_move_iterator(y.begin()), make_move_iterator(y.end()));

一个range-basedfor循环相当于,大约:1)获取容器的开始和结束迭代器,2)使用临时迭代器从开始迭代器值迭代到结束迭代器值 3) 在每次迭代中,取消引用临时迭代器并将范围循环的变量设置为取消引用的迭代器值。

...或多或少。底线是 1) range-based for 循环获取并使用范围的开始和结束迭代器,以及 2) 你声明你的容器是一个向量,并且,如你所知,修改向量正在进行使向量内容的大多数迭代器无效。

的确,通过对向量内容进行某些类型的修改,某些迭代器不会失效,并且会保持有效。但是,实际上,可以安全地假设如果您在某处有 std::vector::iteratorstd::vector::const_iterator,修改向量意味着迭代器不再有效。正如我提到的,并不总是 100% 正确,但这是一个非常安全的假设。

并且由于范围迭代获取并使用容器的迭代器,在迭代的生命周期内,这几乎使得对向量进行范围迭代,并在迭代期间修改向量,non-starter.对于向量的任何连续迭代,对向量的任何修改都可能导致未定义的行为。

请注意,"modification" 本质上意味着从向量中插入或删除值;也就是说,向量本身的修改。修改向量中的 values 对任何现有迭代器的有效性没有影响,这是安全的。

如果你想迭代一个向量,然后在这个过程中安全地修改向量(修改包括从向量中插入或删除值),你必须自己回答的第一个问题是迭代的插入或移除均值。这是你必须自己弄清楚的事情。例如,如果您的循环当前在向量中的第 4 个元素上,并且您在向量中插入一个新的第 2 个值,因为将一个值插入向量中会将向量中的所有剩余值向上移动,因此第 4 个元素在向量中vector 将成为 vector 中的第 5 个元素,如果您设法安全地正确执行此操作,则在下一次迭代中,vector 中的第 5 个元素将与您之前迭代的元素相同。这是你想要的吗?这是你必须首先自己回答的问题。

但就迭代期间安全修改向量而言,最简单的方法是完全避免使用迭代器,并使用索引变量:

for (size_t i=0; i<x.size(); ++i)
{
    auto v=x[i];

    // ...
}

现在,修改矢量是绝对安全的,然后您需要弄清楚的是矢量被修改之后,i 索引变量需要以任何方式调整。

并且那个问题你必须自己回答。