我很高兴在我的代码库中使用
std::flat_map
和 std::flat_set
。在少数情况下,我需要将可搜索的、有序的数据集保留为连续内存,然后将其作为普通 C 样式数组传递到另一个函数中。从历史上看,我通过手动插入排序到 std::vector
或批量插入然后调用 std::sort()
来完成此操作。我将 std::lower_bound()
包装在访问器中进行搜索,访问 ```std::vector::data()`` 就可以了。
通过
std::flat_map
,我在标准中得到了所有这些。但是,API 似乎无法在创建适配器之前保留存储空间。我已经解决了这个问题,方法是首先自己创建键和值的容器,保留每个容器,然后将它们移动到适配器中,但这很麻烦。如果发生批量插入,或者了解感知到的上限变化,它还会阻止我稍后保留额外的存储空间。
根据标准,内部容器似乎是私有的,因此不可能通过子类化来访问它。
std::flat_map::keys()
和 std::flat_map::values()
都返回 const 引用,所以这没有帮助。我想我可以使用 std::flat_map::extract()
返回容器,然后保留更多存储空间,然后就地新原始地图?
这一切看起来有点笨拙。我的目标是减少我的环境中的重新分配(和碎片),在我的环境中,我没有虚拟内存管理器的好处,并且分配成本也并非微不足道。
使用
std::flat_map::replace
功能将 extract
数据移回:mp.replace(
std::move(ex.keys),
std::move(ex.values)
);
您也可以定义调整大小函数:
using my_flat_map = std::flat_map<my_keys, my_values>;
void reserve_map(my_flat_map& mp, std::size_t ks, std::size_t vs = ks){
auto ex = mp.extract();
ex.ks.reserve(ks);
ex.vs.reserve(vs);
mp.replace(
std::move(ex.keys),
std::move(ex.values)
); // mp.replace
};