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

sel*_*bie 1 c++ stdmap std

采取以下简单程序:

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

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

我跑的时候有些惊讶.缓存的指针保持不变:

42 21 11 Hello world
f1 insert location has not changed
42 21 11 Hello world
Run Code Online (Sandbox Code Playgroud)

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

所以我的问题是:插入地图的项目是否保证在同一地址,只要它没有从地图中删除或替换?或者这个实现是否具体?

use*_*670 6

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

26.2.6关联容器[associative.reqmts]
9 insertemplace成员不应影响迭代器和容器引用的有效性,erase成员只能使迭代器和对擦除元素的引用无效.

  • 偶然地,您引用了肯定这一点的参考文献或文档? (2认同)
  • @selbie 从标准中添加了引用 (2认同)