C++之旅(学习笔记)第9章 标准库
当无知稍纵即逝时,又何必浪费时间学习呢?
------霍布斯
9.1 引言
第9~18章将对重要的标准库工具和方法给出一个概要性的介绍。如:string、ostream、variant、vector、map、path、unique_ptr、thread、regex、system_clock、time_zone和complex。
作者说:不要因为对某些细节理解不够充分而心烦或气馁。本章的目的是让我们对最有用的标准库工具有一个基本的了解。
9.2 标准库组件
标准库提供的工具和方法可以分为如下几类:
太多了,只写几个关键的能记住的吧
- 运行时语言支持库(例如:对资源分配、异常和运行时类型信息的支持)。
- C标准库。
- 字符串库。
- 正则表达式库。
- I/O流库。
- 以可移植的方式处理文件系统的文件操作库。
- 容器框架库(vector、map)和算法库(find()、sort()、merge())。也习惯称为标准模板库(STL)。
- 。。。。。。
- 并发程序支持库,包括thread和锁机制。
- 同步协程库及异步协程库。
- 并行库,包含部分数学算法及大多数STL算法的并行版本,比如sort()、reduce()。
- 支持模板元程序设计的工具库(类型特性)、STL风格的泛型程序设计(pair)和通用程序设计(variant和optional)。
- 用于资源管理的"智能指针"库(unique_ptr和shared_ptr)。
- 特殊用途容器库(array、bitset、tuple)。
- 。。。。。。
9.3 标准库的组织
标准库的所有设施都被放在名为std的命名空间中,用户可以通过模板或者头文件来访问。
9.3.1 命名空间
一般来说,将命名空间中的所有名字都导入全局命名空间并不是好的编程习惯。
std::chrono
:chrono时间库,其中包括std::literals::chrono_literalsstd::listerals::chrono_literals
:后缀y表示年,d表示日,h表示小时,min表示分钟,ms表示毫秒,s表示秒,us表示微妙std::literals::complex_literals
:后缀i表示双精度虚数,if表示单精度虚数,il表示long double类型的虚数std::literals::string_literals
:后缀s表示字符串类std::literals::string_view_literals
:后缀sv表示字符字符串视图std::numbers
提供数学常数std::pmr
表示多态内存资源
要使用子命名空间中的后缀,必须将它引入当前的命名空间。
例如:
CPP
//没有引入complex_literals
auto z1 = 2+3i; //错误:没有后缀i
using namespace literals::complex_literals; //引入complex literals 声明的后缀
auto z2 = 2+3i; //可行:z2是complex<double>类型的
9.3.2 ranges命名空间
标准库提供的sort()和copy(),有两个版本:
- 传统版本,接受两个迭代器作为参数:
sort(begin(v),v.end());
。 - 范围版本,接受一个单独的范围:
sort(v);
。
理想情况下:这两个版本(参数不同)应当可以直接重载而不需要任何特殊的动作。但是实际上不行:
CPP
using namespace std;
using namespace ranges;
void f(vector<int>& v) {
sort(v.begin(),v.end()); // 错误:有歧义
sort(v); // 错误:有歧义
}
为避免使用非限定模板时造成的歧义,标准规定了范围版本必须在作用域内显示声明:
CPP
using namespace std;
void g(vector<int>& v) {
sort(v.begin(),v.end()); // 可行
sort(v); // 错误:没有匹配的函数(在std命名空间内)
ranges::sort(v); // 可行
using ranges::sort; // sort(v)现在可行了
sort(v); // 可行
}
9.3.3 模块
目前为止,无任何标准库模块,作者说C++23很可能会弥补这个遗漏。
目前:作者使用可能称为标准的 module std。
9.4 建议
- 不要重新发明轮子,应该使用库。
- 当有选择时,优先选择标准库而不是其他库。
- 不使用模块时,记得用#include包含相应的头文件。
- 记住,标准库工具和方法都被定义在命名空间std中。
- 在使用ranges时,记得显示限定算法名称。
- (如果可用)尽量使用import模块代替#include头文件。