如果我在迭代它时展开容器会发生什么,我可能会遇到新元素或只是旧元素
std::vector<int> arr(0);
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
for (auto& ele : arr) {
if (4 == ele) std::cout << "meet new eles" << endl;
arr.push_back(4);
}
答案 0 :(得分:6)
push_back
可能使向量的任何迭代器无效,你所拥有的是未定义的行为。
std::vector
在内部分配一个数组,其元素连续存储在内存中。为此,它需要预先分配它可能需要的大小的估计,这被称为向量的容量。在push_back
如果达到容量,它将分配一个新的更大的数组,将前一个数组的所有内容复制/移动到新数组,然后删除旧数组。这会使迭代器失效,并继续指向已删除的数组。
另外值得一提的是,新阵列的分配增加了相当大的性能。如果您知道矢量将始终使用reserve()
来预分配内存的大小。
现在,确实如果你预先保留容量并且永远不会超过那个容量,迭代器就会失效(只有过去的迭代器)并且你可以继续增加它们,因为它们指向一个数组连续元素。但我不建议这样做,IMO错误地重新分配矢量的风险是不值得的。
答案 1 :(得分:2)
如果保证永远不会删除元素,那么最简单的解决方案仍然是使用常规for循环。
for(size_t i=0, n=arr.size(); i<n; ++i)
{
if(/* something */)
{
arr.push_back(/* ... */);
++n;
}
}
我知道这是一个微不足道的解决方案,但其他人可能会搜索并找到这个问题。
来自@Long_GM的好评。这不适用于每个容器。无论是否插入任何值,std :: map都不能以这种方式迭代。