C ++通过扩展容器迭代

时间:2015-09-25 07:02:16

标签: c++ iteration containers

如果我在迭代它时展开容器会发生什么,我可能会遇到新元素或只是旧元素

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);
}

2 个答案:

答案 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都不能以这种方式迭代。