C++ 为什么在使用迭代器时添加到向量不起作用?

C++ 为什么在使用迭代器时添加到向量不起作用?,c++,c++11,vector,iterator,c++-standard-library,C++,C++11,Vector,Iterator,C++ Standard Library,我有两个代码示例,它们做完全相同的事情。一个是C++03和C++11 C++11 int main() { vector<int> v = {1,2,3}; int count = 0; for each (auto it in v) { cout << it<<endl; if (count == 0) { count++;

我有两个代码示例,它们做完全相同的事情。一个是C++03和C++11

C++11

int main()
{
    vector<int> v = {1,2,3};

    int count = 0;

    for each (auto it in v)
    {
        cout << it<<endl;

        if (count == 0)
        {
            count++;
            v.push_back(4);//adding value to vector
        }
    }

    return 0;
}
这里,内联函数显然需要
\u Mylast
来计算结束。所以,当我添加时,它的指针将增加到下一个位置,如
\u Mylast++
。为什么我会得到这个例外


谢谢。

向量将其元素存储在连续内存中。如果需要重新分配内存块,迭代器将无效

如果需要在迭代时修改向量的大小,请按索引而不是
迭代器
进行迭代

另一种选择是使用具有不同迭代器行为的不同容器,例如,
列表将允许您在插入项时继续迭代


最后,(我敢这么说吗?)如果您知道向量将增长到的最大大小,
.reserve()
在对其进行迭代之前将其保留。这将确保它不会在循环期间被重新分配。我不确定这种行为是否得到了标准的保证(也许有人可以插话);考虑到按索引进行迭代是完全安全的,我绝对不会这样做。

向量将其元素存储在连续内存中。如果需要重新分配内存块,迭代器将无效

如果需要在迭代时修改向量的大小,请按索引而不是
迭代器
进行迭代

另一种选择是使用具有不同迭代器行为的不同容器,例如,
列表将允许您在插入项时继续迭代


最后,(我敢这么说吗?)如果您知道向量将增长到的最大大小,
.reserve()
在对其进行迭代之前将其保留。这将确保它不会在循环期间被重新分配。我不确定这种行为是否得到了标准的保证(也许有人可以插话);考虑到按索引进行迭代是完全安全的,我绝对不会这样做。

您的
push_-back
将使您在
for
循环中使用的迭代器无效,因为向量正在重新分配其内存,这将使所有迭代器对向量的元素无效

解决这个问题的惯用方法是使用
insert\u迭代器
,就像在向量上调用
std::back\u inserter
得到的迭代器一样。然后你可以做:

#include <iostream>
#include <iterator>
#include <vector>

int main()
{
  std::vector<int> v;
  auto inserter = std::back_inserter(v);
  for(int i=0; i<100; ++i)
    inserter = i;

  for(const auto item : v)
    std::cout << item << '\n';
}
#包括
#包括
#包括
int main()
{
std::向量v;
自动插入器=标准::背面插入器(v);

for(int i=0;i您的
push_back
正在使您在
for
循环中使用的迭代器无效,因为向量正在重新分配其内存,这将使所有迭代器对向量的元素无效

这方面的惯用解决方案是使用
插入迭代器
,就像在向量上调用
std::back\u inserter
得到的迭代器一样。然后可以执行以下操作:

#include <iostream>
#include <iterator>
#include <vector>

int main()
{
  std::vector<int> v;
  auto inserter = std::back_inserter(v);
  for(int i=0; i<100; ++i)
    inserter = i;

  for(const auto item : v)
    std::cout << item << '\n';
}
#包括
#包括
#包括
int main()
{
std::向量v;
自动插入器=标准::背面插入器(v);

for(int i=0;i“for each,in”不是标准的。for each,in范围内的c++11不是标准的。for each,in范围内的c++11是用于(Type name:collection)。
resize
如果后跟
push_
-
at
操作符[]在这种情况下应使用
reserve
push_back
配合使用,因为它不改变大小,只改变容量。就我个人而言,我坚持“不要修改您迭代的内容”原则。
std::deque
是保持迭代器有效的
std::vector
的一个很好的替代方法。
resize
如果后跟
push_back
-
at
操作符[]
应该在这种情况下使用。
reserve
push_back
配合使用,因为它不会改变大小,只会改变容量。就个人而言,我坚持“不修改迭代内容”原则。
std::deque
std::vector
的一个很好的替代方法,如果你想保持迭代器的有效性。
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
  std::vector<int> v;
  auto inserter = std::back_inserter(v);
  for(int i=0; i<100; ++i)
    inserter = i;

  for(const auto item : v)
    std::cout << item << '\n';
}