代码之家  ›  专栏  ›  技术社区  ›  selbie

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

  •  1
  • selbie  · 技术社区  · 7 年前

    以下面的简单程序为例:

    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绝对做的那样。

    1 回复  |  直到 7 年前
        1
  •  6
  •   user7860670    7 年前

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

    26.2.6关联容器[关联需求]
    insert emplace 成员不得影响迭代器和容器引用的有效性,以及 erase 成员应仅使迭代器和对已删除元素的引用无效。