让我们从C ++中的示例代码开始:
#include <vector>
#include <iostream>
int main()
{
std::vector<int> vec;
vec.push_back(0);
for (int i = 1; i < 5; i++)
{
const auto &x = vec.back();
std::cout << "Before: " << x << ", ";
vec.push_back(i);
std::cout << "After: " << x << std::endl;
}
return 0;
}
代码使用g++ test.cc -std=c++11 -O0
进行编译,结果如下:
Before: 0, After: 0
Before: 1, After: 0
Before: 2, After: 2
Before: 3, After: 3
我期待第二行输出
Before: 1, After: 1
因为x
是对向量中项目的引用,不应通过将项目附加到向量来修改该项目。
但是我现在还没有阅读反汇编代码或进行任何其他调查。此外,我不知道这是否是语言标准中的未定义行为。
我希望对此进行解释。感谢。
答案 0 :(得分:8)
23.3.6.5
向量修饰符,draft C++ standard可能会导致重新分配:
void push_back(const T&amp; x);
void push_back(T&amp;&amp; x);
备注:如果新大小大于旧容量,则会导致重新分配。 如果没有重新分配,插入点之前的所有迭代器和引用仍然有效。
我们可以看到back为我们提供了引用,因此如果有重新分配,它将不再是有效。
答案 1 :(得分:4)
vector
迭代器(以及对元素的先前引用)可能会失效。使用它们是不安全的。