C++17 详解 25 —标准库的其它变动
本文为 《C++17 in detail》 一书的中文渣中渣译文,不足之处还望指正。
翻译太特么累人了……剩余部分还是只做摘要翻译吧。
14. STL 其它改动
14.1 std::byte
类型安全的字节表示,不是数值型值。
定义:
1 | enum class byte : unsigned char {} ; // in <cstddef> |
可以通过 unsigned char 初始化 b{unsigned char},也可以通过 std::to_integer() 转换成数值类型。
14.2 map 和 set 改进
拼接(splicing)
新函数:set/map::extract()
1 | std::set<User> setNames; |
将 John 从 setNames 提取出来,然后把它插入 outSet。
- extract 返回 node_type 类型的节点句柄。
- node_handle 是一个只可移动类型,移动构造函数从对象中取走容器元素所有权。
- User 不需要定义移动构造函数就可以使用 extract(node_handle 持有
node*
,node*
持有 User)。
对 map 和 unordered_map 的 emplace 加强
新加 try_emplace() 函数:如果指定键值已经存在不做任何事情,否则执行 emplace()。
新加 insert_or_assign() 函数:插入新键值对或更新已存在键的值,值以移动构造方式转移进容器。
14.3 emplace 函数的返回值类型
由 void 改为了 T&
1 | // C++17 前的 std::vector |
14.4 采样算法
std::sample:从序列中选择 n 个元素。
1 |
|
14.5 新的数学函数
<numerics>
头文件:
- std::gcd:最大公约数
- std::lcm:最小公倍数
<algorithm>
头文件:
- std::clamp(v, min, max)
<cmath>
头文件:
- assoc_laguerre
- assoc_legendre
- beta
- comp_ellint_1
- comp_ellint_2
- comp_ellint_3
- cyl_bessel_i
- cyl_bessel_j
- cyl_bessel_k
- cyl_neumann
- ellint_1
- ellint_2
- ellint_e
- expint
- hermite
- laguerre
- legendre
- riemann_zeta
- sph_bessel
- sph_legendre
- sph_neumann
译注:完全没了解。
14.6 shared_ptr 和数组
现在 shared_ptr 持有数组不需要指明自定义 deleter 了:
1 | std::shared_ptr<int[]> ptr(new int[10]); |
make_shared 还不支持数组,需要等到 C++20。
14.7 非成员的 size()、data()、empty()
头文件:
1 |
14.8 标准库里 constexpr 的增加
C++17 开始添加容器类的 constexpr 构造能力;C++20 添加 constexpr 算法的能力。
14.9 std::scoped_lock
scoped_lock 可以对多个 mutex 同时 lock:
1 | std::scoped_lock lck(first_mutex, second_mutex); |
14.10 std::iterator 被弃用
自定义迭代器类时不需要再从 std::iterator 继承,虽然需要显式地定义类型萃取的各个部分,但是代码变得更清晰了。
旧:
1 | class ColumnIterator |
新:
1 | class ColumnIterator { |
14.11 多态化的分配器(Allocator),pmr
预置了几种不同内存分配策略的分配器。
pmr:Polymorphic Memory Resource,多态内存资源。