造轮子 | C++ STL 缺失的几个容器
1. 简介
C++ 标准容器不够用,问题主要在性能的一些方面。
一方面是小容器,C++ 对此有特殊优化(MSVC有,gcc clang等没去看源码,不确定)的是 ,当字符串比较短时,使用的是对象的内置空间来存储,当字符串较长时,就改用动态分配的空间。但其余容器(如
,
等)就没有此类优化了。同时,标准库里也没有提供此类容器(例如 boost 的
)。
另一方面是 set 和 map 底层用了红黑树,而有时候我们需要的是一个有序连续序列容器。这类容器对应的是 boost 的 和
。此类容器在小容器的情况下会比红黑树快一些,搭配 small_vector 极佳。
GitHub 上没有我满意的轻量级实现,因此就我来造这些轮子吧。
https://github.com/Ubpa/UsmallFlat
纯头文件,直接拷贝拖进项目里就可以用。基于 C++20 实现。
2. 轮子总览
这次我造的轮子有
一开始叫,用于表示固定容量 fixed capacity,由于容易产生歧义,故改为主流的
。
:固定容量的
,接口上类似
,区别在于其在对象内有固定大小的空间用于存储数据,但容量有限,不可扩充。
: 类似
,区别在于其在对象内有固定大小的空间用于存储数据(用
实现)。当元素个数超过该固定大小时,会动态分配空间用于存储所有数据。
:类似
,区别在于其底层并非是红黑树,而是一个有序数组,因此可以提供
等接口。
:类似
,区别在于并非是红黑树,而是一个有序数组,因此可以提供
等接口。实际上它是用
实现的。
以上是四个核心容器。 容器能用来实现非
的容器,因此还有以下容器
: 类似
,区别在于其底层并非是红黑树,而是一个有序数组,因此可以提供
等接口。 实际上它是用
实现的。
:类似
, 区别在于其底层并非是红黑树,而是一个有序数组,因此可以提供
等接口。 实际上它是用
实现的。
这里 的指的是这类容器允许用户使用自己的
作为底层容器。 因此通过结合
,
,
和
, 又能多出大概 5 * 4 = 20 个容器。
上述容器的接口遵循标准容器。
关于 flat 容器的算法复杂度问题,各接口主要用了二分法 + vector,所以复杂度问题上都是挺直观的,具体可参考 boost 的说明 boost | flat_set 等。
3. 使用示例
常用容器为
:
+
,
,
,
:
+
,
,
,
:
+
用法上完全同于标准容器。基本支持一切 C++11/14/17/20 的接口(除了 set 和 map 的 node 相关接口,因为这里的容器为 flat,没有 node 的概念)。对于 flat 容器,还额外新增 vector 的接口(data,capacity,front,back,reserve,shrink_to_fit)。
这里就简单举例一下:

4. 总结
欢迎使用,感谢阅读!如有错误,欢迎指正,感谢各位。
整理了一些最新LinuxC/C++服务器开发/架构师面试题、学习资料、教学视频和学习路线脑图(资料包括C/C++,Linux,golang技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享有需要的可以自行添加学习交流群960994558进群领取!~