修改了vector之后对vector.back()的引用的奇怪行为

sta*_*ify 6 c++ reference vector c++11

让我们从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;
}
Run Code Online (Sandbox Code Playgroud)

代码是用g++ test.cc -std=c++11 -O0以下编译的,结果如下:

Before: 0, After: 0
Before: 1, After: 0  
Before: 2, After: 2
Before: 3, After: 3
Run Code Online (Sandbox Code Playgroud)

我期待第二行输出

Before: 1, After: 1
Run Code Online (Sandbox Code Playgroud)

因为x是对向量中的项的引用,不应通过向向量附加项来修改该项.

但是我现在还没有阅读反汇编代码或进行任何其他调查.此外,我不知道这是否是语言标准中的未定义行为.

我想要解释一下.谢谢.

Sha*_*our 8

push_back可以导致重新分配,如果我们看一下草案C++标准部分23.3.6.5 向量修饰符说:

void push_back(const T&x);

void push_back(T && x);

备注:如果新大小大于旧容量,则会导致重新分配.如果没有重新分配,插入点之前的所有迭代器和引用仍然有效.

我们可以看到back给了我们一个参考,所以如果有重新分配它将不再有效.