在 Vectors 中使用 for range 来添加元素

Usage of for range in Vectors in order to add elements

这里问了很多关于for range的问题,但是我找不到我需要的版本。 所以,我正在阅读这本名为 C Primer 第五版的书,在阅读有关 Vectors 的内容时,我读到一行内容, 如果循环体向向量添加元素,我们不能使用范围。 但是就在这一行之前,有一个代码部分被编写为在 运行 时间期间在向量中添加元素,即

vector<int> v2; // empty vector
for (int i = 0; i != 100; ++i)
v2.push_back(i); // append sequential integers to v2
// at end of loop v2 has 100 elements, values 0 . . . 99

我只想问,这两者怎么会矛盾呢?或者它们完全不同并且彼此无关?如果第二个是条件,你能解释一下这是如何工作的吗? 如果前者是正确的,你能解释一下为什么代码部分和声明相互矛盾吗?

基于范围的 for 循环(除其他事项外)不应附加元素的原因是因为在幕后,基于范围的 for 循环只是一个从头到尾遍历容器迭代器的循环. std::vector::push_back 将使所有迭代器失效:

If the new size() is greater than capacity() then all iterators and references (including the past-the-end iterator) are invalidated. Otherwise only the past-the-end iterator is invalidated.

然而,与使用迭代器相反,在索引向量时不能说相同,因为即使 push_back 使迭代器无效,vec[3] 将始终引用位置 [=14= 处的元素](假设 size() > 3)。

此外,您显示的循环甚至没有遍历向量的元素。它只是向现有向量添加更多元素,and 它不是 range-based for loop.

需要说明的是,可能会出现问题的构造如下:

std::vector<int> vec(10); // 10 times a zero
vec[0] = 1;
for (int k: vec)
  if (k == 1)
    vec.push_back(2); // invalidates iterators!

虽然这个看起来相同的代码是合法的:

std::vector<int> vec(10); // 10 times a zero
vec[0] = 1;
for (std::size_t i = 0; i < std::size(vec); ++i)
  if (vec[i] == 1)
    vec.push_back(2);