本文主要内容为 侯捷先生 的《STL标准库与泛型编程》课程个人学习记录,并非完全照搬讲义,有机会请读者看原视频。
STL结构
泛型 for
c++11之后,提供了泛型for,更方便的用在容器遍历。
std::vector<int> v = {1,2,3};
for (auto &it : v)
{
std::cout << it <<std::endl;
}
容器自带的的sort、find与count
- list与forward_list由于其内部分别是双链表与单链表实现,所以内部自己实现了sort,就不使用全局的sort。
- set/multiset、map/multimap,其内部实现都是红黑树,自然有序,所以有自己更快捷的find与count。
- unordered_set/unordered_multiset、unordered_map/unordered_multimap,其内部是hashtable,所以也有自己的find。
模板偏特化
模板偏特化分为参数数量上的特化,也可以是参数范围上的特化。全部模板参数都指定为全特化,否则为偏特化。关于模板知识点还有我的其他一篇 C++ typename与非类型类模板参数
注:对于模板,编译器并不会执行严格检查,经常当编译时才会发现问题。
关于malloc与free
所有c++ 的new或者分配器等等内存分配方式,最后都转向了malloc,注意的是malloc在分配空间的时候,会多分配一点内存空间,用于存储这次分配内存大小的信息,称为cookie。这也是使用free归还内存的时候为什么不需要指定大小的原因。具体还有一篇内存关系细说。
iterator_traits/type_traits
可称为萃取机,主要用于获取迭代器和类型的相关特征。例如迭代器是否是随机访问,回答算法的提问,便于算法进行相应的优化;又例如回答类型是否有 不重要的构造函数,以便进行相应的优化。当然其实现并不神奇,即为迭代器和类型都按照一定的规则来定义相应属性(使用typedef)。
stack与queue
这两者都是所谓的容器适配器,因为其本身没做什么,只是将所有操作转交给其包含的低层结构,底层结构可以是list和deque(默认)。
set/**multiset、map/multimap
map独有[]操作:若key存在,则返回对应的value,若不存在,则创建一个key,并使用默认值作为value。由于返回了引用,可以用于插入数据,不过没有直接插入操作快,毕竟多了个二分查找key是否存在的过程。
C++11给Non-static Data Member赋值
就是在定义类非静态的数据成员时可以给初值。参考的我另一篇 C++11给Non-static Data Member赋值
hashtable
当元素个数大于篮子数目是rehash。
iterator_category
算法根据不同的迭代器类型算法采取不同的操作:
- distance:获取两个iterater的距离(如果是随机的迭代器,则可以直接相减得到结果,否则就要一个个数)。
- advance:将迭代器前进n个位子。
- copy:复制
- destroy:销毁数据
常用算法
accumulate
for_each
replace/repace_if/repace_copy
count/count_if
find/find_if
sort
binary_search
reverse iterator
仿函数可适配的条件
继承这两者,主要是表明自己是一元函数还是二元函数,同时规定了参数和返回值的类型。
多种适配器
其中容器适配器是指:stack和queue。
仿函数适配器主要有:
#include<functional>
//bind 使用其中的占位符 _1 _2
using namespace std::placeholders;
//not1 对 仿函数 取反
//bind
迭代器适配器
type traits
type traits 实现原理
原理可参考我的另外一篇:C++ type_traits实现原理