根据这个你不能为std::map以下空间预留空间:
不,地图的成员内部存储在树结构中.在知道要存储的键和值之前,无法构建树.
从这一点可以明显看出为什么std::map缺少一种reserve()方法,它在cppreference.com上做了.但是,std::unordered_map 确实有一个reserve()方法,但是当我尝试使用它时operator[],insert()或者emplace()尽管我reserve()先调用它们,它们都会分配内存.
怎么了?为什么不能reserve()妥善保留所需的空间?如果它与地图一样,你不能事先分配内存,那为什么std::unordered_map甚至首先有一个reserve()方法呢?
我有一个类 (A),其复制构造函数被删除 ( =delete;),移动构造函数和移动赋值被声明和定义。该类持有的资源不得释放两次,因此存在仅移动限制。
我有另一个类 (B),它保存 A 的实例(不是指针)。我为 B 类编写了一个移动赋值运算符,它调用std::move()A 类的成员。
映射包含 B 的许多实例。我创建 B 的实例并直接通过赋值为其分配 A 成员。然后我尝试将 B 插入到地图中。我已经尝试过operator[],insert并emplace以不同的方式,但我不断收到错误,声称我正在尝试使用带有签名的已删除函数A(const A&)。那么尽管它被删除了,它还是试图使用复制构造函数?
一切都很好,直到我尝试将其插入地图中。
我用的是VS2013。
编辑:对于我的项目来说很重要(可能与所讨论的问题无关),我最终使用的方法不会与WinAPI (kernel32/ntdll 等)执行任何库交互,因此任何operator new()内部调用或类似的方法委托给 WinAPI 我将无法使用。该地图已预先分配reserve()以试图缓解这一问题。
代码(调用emplace是导致编译错误的原因):
/* main.cpp */
#include "smart_handle.h"
#include <unordered_map>
#include <Windows.h>
struct MetadataStruct
{
MetadataStruct& operator=(MetadataStruct&& other)
{
if (this != &other)
{
handle = std::move(other.handle);
// Invalidate other.handle somehow...
}
return *this; …Run Code Online (Sandbox Code Playgroud)