《C++标准库》第5章 通用工具
pair和tuple
便捷函数make_pair()
Template函数make_pair(),能够让我们无须写出类型就能生成一个pair对象。
make_pair函数的自动推断有时候可能并非用户所想,一个表达式用户明白的指出类型时,产生出来的pair将有绝对明确的类型
Tuple(不定数的值组)
Tuple中的每个类型由默认构造函数初始化,基础类型都会被初始化为0
get函数所需要的index必须在编译期已知,运行期再传入一个值是不被允许的:
便捷函数ref和cref应用于Tuple
智能指针
shared_ptr
显式构造函数不能使用赋值符
对付Array
shared_ptr提供的默认删除器调用的是delete,而不是delete[]。这意味着如果我们想要使用指针指针指向一个数组,我们需要自定义delete[]删除器
不要误用shared_ptr
第二个智能指针不要传底层指针作为参数,而是得传第一个智能指针作为参数
reset函数
Unique_ptr
不可以对unique_ptr执行copy和assign
注意第三个语句,可以传一个右值unique_ptr作为构造函数的参数
赋予新值必须是unique_ptr
unique_ptr转移的源头和去处
函数端:
unique_ptr作为函数实参,传参要使用move语义
供应端:
函数返回一个右值指针
习惯将unique_ptr当作成员
数据成员包含unique_ptr,在构造函数传入对应的数据时对ptr进行初始化。这样就可以预防因构造函数产生异常而导致的资源泄漏。这样处理之后甚至不用写构造函数,因为智能指针在对象销毁时会自动释放资源。
但此时我们应该写出copy构造函数和赋值操作符。如果没有自行提供,编译器将会默认生成move语义版本
对付array,偏特化
该class不接受一个派生类型的array作为初值,所以在array身上起不了多态作用
智能指针结语
shared和weak指针内部都需要额外的辅助对象,以内部pointer指向(引用计数器等)。这会导致额外的内存开销,无法进行许多优化动作。
Unique_ptr 则完全不需要这样的额外开销,使用它和使用原生指针效率几乎相同
数值的极值
class numerical_limit<>
该模板类中含有内置数值类型的很多信息,它们以类的静态数据和静态函数的形式存在,大多数成员被声明为constexpr,它们在编译期就可以进行访问
用例:
Type Trait和Type Utility
基本用法举例
type Trait是用来处理类型属性的办法。它是个template,可在编译期根据一个或多个template实参产出一个type或value
上述例子就用到了type Trait来判断传入类型是否为指针,将其改为重载函数的形式:
在调用重载函数时使用type trait,根据传入的是std::true_type还是std::false_type来判断是否为指针。
处理共通类型
当两个不同类型的值进行运算时,该返回什么共通类型呢?
类型判断式
如果该类型满足特定的性质,则它的内部静态成员变量value的值为std::true_type,否则为std::false_type。
用例:
用以校验类型关系的Trait
检查类型之间的关系,检查class提供了哪一种构造函数和哪一种赋值操作
例子:
类型修饰符
使用下列方法可以对类型进行改动,比如原来该类型不为const,使用方法后可以变为const。
但要注意的是这里针对的是类型,而不是实际的对象
例子:
其他Type Trait
用来查询特殊属性、检查类型关系或提供更为复杂的类型变换
例子:
Reference Wrapper(外覆器)
Function Type Wrapper(外覆器)
class std::function<>,声明于, 提供多态外覆器。可以借用这个将函数、函数指针、lambda表达式、可调用类这些可调用对象统一类型。
辅助函数
最值函数
minmax<>返回一个pair<>,first是最小值,second是最大值
交换 swap
增补的“比较操作符”
Class ration<>的编译期分数运算
使用该模板类可以指定编译期分数,并允许对它们执行编译期运算:
num是分子,den是分母
用例:
四则运算和逻辑判断
注意:判断产生的结果为true_type 或 false_type, 而不是一般的true、false
例子:
分数预定义类型
Clock 和 Timer
定义于<chrono>的chrono程序库用来处理日期和时间
chrono程序库概览
Duration、timepoint
duration用于表示一段时间,这段时间可以有多种表示方法。比如10分钟,可以表示为10个1分钟、60*10个1秒、1/6个1小时。这里的1分钟、1秒、1小时代表的是时间单位,而10、60*10、1/6则代表了tick。
timepoint用于表示某个时间点,在表示一个时间点之前需要像坐标轴以像先定好一个原点,这个原点就是epoch。某个时间点表示为“epoch要经过多少duration才能到达该时间点”。和坐标点到原点的距离类似
Duration(时间段)
在模板参数中,第一个模板参数是表示tick数的数值类型,该数值在创建对象时给出。第二个模板参数是时间单位,以分数的形式表示“一个当前单位占了多少秒”
Duration的算数运算
例子1:单位类型不同也可以运算,运算结果会采用两个操作数单位的最大公约数
例子2:大单位可以转换成小单位,反之则不行。
Duration的其他操作
例子:
Clock(时钟)和Timepoint(时间点)
Clock(时钟)
这三个clock都是类型
例子:
Timepoint(时间点)
用例:
注意这里获取的日历表示法是根据用户所在时区获取到的
注意这里是直接调用clock命名空间下的类型或者是静态函数获取timepoint,和之前通过模板参数获取的方式不同
时间点操作函数
C和POSIX提供的Date/Time函数
以计时器停滞线程
头文件<cstddef>、<cstdlib>、<cstring>
<cstddef>内的各项定义
C++11后引入了nullptr,现在我们应该使用它来代替NULL,表示空指针情况
<cstdlib>内的各项定义
这两种退出都不会清理局部对象,如果希望能够进行清理,可以使用异常机制。
<cstring>中的定义式
memcmp、memcpy、memset经常会用到