前言
C++ 标准库中有被称为 STL (常被视为标准模板库, standard template library 的缩写)的组件。其外延往往是不统一的:
最广的可见于 microsoft/STL ——指代 C++ 标准库中来自 C 标准库以外的部分。最狭义的看法可能认为 string
不属于 STL ——因为尽管现在它是 basic_string
的特化,但它在 C++ 有模板之前就出现了。
这里,我希望从 STL 的起源—— SGI STL 的内容出发,尝试界定一下 STL 在 C++20[1] 的发展,确定一个比较清晰的外延。
SGI STL 的内容
SGI STL 的内容大概如下:
- 容器
- 字符串、
char_traits
- 泛型、数值算法
- 随机数生成器
- 迭代器工具及迭代器适配器
- 运算符函数对象、函数适配器、
hash
pair
allocator
- 容器和迭代器的具名要求(在 SGI STL 文档中被称为“概念”)
另外 SGI STL 的工具还有这样的特征:
- 不做类型擦除
- 需要定制分配释放时,都使用分配器
C++20 中适合称为 STL 的部分
这里我试图从 C++20 中找出 SGI STL 组件的后裔,给 STL 一个更合适的外延。这里包含主观判断,不宜视为公论。
C++20 出现了各种视图相关工具,这里我认为它们是算法库中原本就隐含的概念的实现,将它们一同视为 STL 的后裔。
算法
<algorithm>
<execution>
<numeric>
<memory>
的一部分(含uninitilized_*
系列、destroy
系列、construct_at
)<utility>
的一部分(swap
、exchange
)
注:以上内容包括并行算法及执行策略。
随机数
<random>
容器及视图
<array>
<deque>
<forward_list>
<list>
<vector>
<map>
<set>
<unordered_map>
<unordered_set>
<queue>
<stack>
<span>
注:暂且认为 pmr
下使用 polymorphic_allocator
的容器也算是 STL 的一部分,视为使用一种分配器的特殊情况,而非使用类型擦除。(与后面有一些不一致)
注:虽然许多容器类包含 <initializer_list>
,但这里不将其内容视为 STL 的一部分,而是认为它更接近内建类型。
类似容器的工具
<bitset>
更多的范围工具
<ranges>
分配器相关工具
<memory>
的一部分(allocator
及辅助函数、allocator_traits
、uses_allocator
及辅助函数、allocator_arg
、pointer_traits
、to_address
)<scoped_allocator>
注:这里不计入 <memory_resource>
,因为它主要目的是把内存资源多态化,且进行类型擦除。
字符串工具
<string>
<string_view>
迭代器工具及适配器
<iterator>
函数对象
<functional>
的大部分(除了function
及其辅助)
注:这里不包括 function
的原因是它的目的含有类型擦除。
pair
及其延伸
<utility>
的一部分(pair
及关联函数、piecewise_construct
)<tuple>
概念
<concepts>
注: <iterator>
与 <ranges>
也含有概念。
部分包含的头文件及其理由
排除 <memory>
中智能指针( unique_ptr
、 shared_ptr
、 weak_ptr
及其辅助类、函数)、垃圾收集器接口( pointer_safety
等)部分。理由如下:
unique_ptr
的始源是独立发展的auto_ptr
,且通过删除器而非分配器定制内存管理策略;默认与 new 表达式耦合更紧密。shared_ptr
类似,而且进行类型擦除;weak_ptr
为其辅助。- GC 接口为独立发展,与泛型关联不密切。
排除 <functional>
中 function
及其辅助类、函数。理由如下:
function
进行类型擦除。
排除其他头文件中间接包含的 <initializer_list>
组件。理由如下:
initializer_list
属于更加基础的工具,在 C++ 标准中被当作语言支持库的一部分。
仅包括 <utility>
中 pair
的辅助函数及类、 swap
、 exchange
。理由如下:
pair
被列为 SGI STL 的组件。swap
被列为 SGI STL 的组件;古代 C++ 中swap
属于<algorithm>
。exchange
性质与swap
相似。(这更多是我个人评判)
总结
SGI STL 及其派生后裔的内容在今天的标准库中有些零散,但也有聚集的趋势。
这里无法奢求给 C++ 标准库中的 STL 下一个公认定义,只作为一个(尽可能接近准确)的参考。
参考
- ^C++20 尚未正式发布,内容可从最终草案 N4861 查看,实际标准可能继续修正一些小错误) https://timsong-cpp.github.io/cppwp/n4861/