std::map 中的项目是否永远保留在同一个地址?

Do items in a std::map stay at the same address forever?

采用以下简单程序:

struct Foo
{
    int x;
    int y;
    int z;
    string s;
};

int main()
{
    Foo f1 = { 42,21,11, "Hello world" };
    std::map<int, Foo> foomap;

    foomap[400] = f1;
    Foo* ptr = &foomap[400]; // cache a pointer to the element we just inserted.

    cout << ptr->x << " " << ptr->y << " " << ptr->z << " " << ptr->s << std::endl;

    // fill the map up with a bunch of other random items at random indices   
    for (int x = 0; x < 10000; x++)
    {
        int i = rand();
        Foo f = { rand(), rand(), rand(), "Another string" };

        if (foomap.find(i) == foomap.end())
        {
            foomap[i] = f;
        }
    }

    Foo* ptr2 = &foomap[400];

    cout << "f1 insert location has " << ((ptr == ptr2) ? "not changed" : "changed") << std::endl;
    cout << ptr->x << " " << ptr->y << " " << ptr->z << " " << ptr->s << std::endl;

    return 0;
}

所以上面的程序缓存了一个指向地图中的项目的指针。然后将更多项目添加到地图中,然后验证第一个插入的项目是否已更改位置。

当我 运行 它时,我有些惊讶。缓存的指针保持不变:

42 21 11 Hello world
f1 insert location has not changed
42 21 11 Hello world

我会假设随着地图中项目数量的增长,实现可能会移动项目 - 就像 std::vector 绝对那样。

所以我的问题是:插入到地图中的项目 gua运行 是否一定位于同一地址,只要它没有从地图中删除或替换?或者这个实现是特定的?

是的,地图上的插入/放置操作永远不会使迭代器或对现有项目的引用无效。

26.2.6 Associative containers [associative.reqmts]
9 The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.