unordered_map 中的项目是存储在堆栈中还是堆中?

Are items placed in an unordered_map stored in the stack or the heap?

假设我有以下 class:

class MyOtherClass{
     std::unordered_map<int, std::multimap<int, MyClass*>> _xy;

     void putObject(int x,int y,MyClass* obj);
     void containsXkey(int x){
         bool found = false;
         std::unordered_map<int,std::multi map<int,MyClass*>>::const_iterator index = _xy.find(x);

         if(index = _xy.end(){
               found = false;
         }else{
               found = true;
         }

          return found;
     }
}

假设我想写一个函数在坐标 (2,3) 处放置一个 MyClass,那么我会这样做:

void putObject(int x, int y, MyClass* obj){
    if(!containsXKey(x){
          //Since it doesn't contain an empty multimap, I'm creating one.
          std::multimap<int, MyClass*> foo; //This is created on the stack
          _xy[x] = foo; //What happens here ?
    }

    std::multimap<int,MyClass*>& foo = _xy[x];
    foo.insert(y,obj);
}

所以我的问题是:最初 unordered_map 中没有条目,所以我第一次想在特定键上添加项目时,我需要创建一个 multimapmultimap 是在堆栈上创建的。那么当我将它分配给 key 时会发生什么?它正在复制吗?它存储在哪里?

与所有动态大小的容器一样,地图容器将其元素保存在动态内存存储中*("heap"**)。
对象本身可能位于堆栈、堆等位置,但在对象内部可能存在指向动态内存的子对象或指针。

So what happens when I assign it to the key?

映射将确保内部缓冲区可以容纳另一个键值对,如果不能,它将扩展以支持存储更多元素。

Is it making a copy?

这取决于 key/value 是如何传递到地图的。如果 key/value 支持移动语义并且键作为 r-value-reference 传递,它将不会被复制,而是 moved。但如果 class 不支持移动语义或密钥作为常量引用传递,它将被复制。

Where is it being stored ?

该标准并未强制规定应如何在内部实施地图,因此每个图书馆都可以随心所欲地实施它。 Microsoft std::unordered_map 将键值对保存在链表中,其他库可能会选择将映射元素保存在向量中。

      std::multimap<int, MyClass*> foo; //This is created on the stack
      _xy[x] = foo; //What happens here ?

在这种情况下,foo 是在堆栈上创建的。运算符 [] 本身在堆上创建一个默认创建的 std::multimap,然后运算符 =foo 的内容(非)复制到 _xy[y] 中。

*假设映射使用标准分配器,可以设置从其他存储分配内存的特定分配器。

** 标准没有直接表述"stack"和"heap"等词,而是表述了以下术语:自动存储("the stack")、动态存储("the heap")、静态存储("the data segment")和线程存储("TLS")。