我想push_back
在迭代向量时修改()元素,如下所示:
auto main() -> int {
std::vector<double> v { 1, 2, 3 };
for (auto& num : v) {
std::cout << num << "\n";
v.push_back(num);
}
std::cout << "===========\n";
for (const auto& num : v) {
std::cout << num << "\n";
}
}
输出为:
1
1.00938e-320
0
===========
1
2
3
1
1.00938e-320
0
为什么输出不是这样的:
1
2
3
===========
1
2
3
1
2
3
如果基于的范围只是糖:
for (auto& it{v.begin()}, it != v.end(), it++)
这里不应该有两种可能的情况吗?
v.end()
每次迭代都会进行评估,并且永不结束。这应该是一个无限循环。v.end()
在迭代之前评估一次并且应该按我预期输出:
1
2
3
===========
1
2
3
1
2
3
正如您致电时所看到的
std::vector::push_back
:(重点是我的)
基于范围的循环只是使用迭代器的语法糖。
在 期间
push_back
可能vector
需要调整大小并重新分配。在这种情况下,所有迭代器都无效,包括用作循环中的“当前”迭代器。使用它会导致未定义的行为。
即使没有重新分配,检查时也会遇到问题
end()
:在循环开始前会查询一次。
与 C++17 有细微的差别。但无论如何,
push_back
在循环内调用都会调用未定义的行为,因为end()
循环前的查询不再有效。这意味着标准不保证程序的输出。您观察到的任何输出都是合法的。