泛型
why泛型:为了让库更一般化。比如find,可以将三样东西都参数化
1)查找对象的类型
2)该对象在数据结构中的组织方式
3)满足某某条件地查找
what仿函数:定义了operator()的对象
why仿函数:
1)使泛型算法更一般化
2)仿函数有自己的独特状态
仿函数可以有不同的状态。所以可以产生多个函数实体。
并且,可以在运行时被调用之前调用它们
3)仿函数有自己的独特类型
每个仿函数都有其类型。因此你可以将仿函数的类型当做template参数来传递。
此外,容器类型也会因为仿函数的不同而不同
4)执行速度上,仿函数通常比函数指针更快
5)如果用函数指针,不能满足stl对抽象性的要求,也不能满足软件积木的要求——函数指针无法和stl其他组件(如配接器adapter)搭配,产生更灵活的变化
when仿函数:
排序准则、搜寻准则,定义某种操作
函数配接器
(Function Adapters)p306
what函数配接器:将仿函数和另一个仿函数(或某个值,或某个一般函数)结合起来的仿函数
函数配接器本身也是仿函数,故可以结合仿函数以形成更强大更复杂的表达式
why函数配接器:通过它们之间的绑定、组合、修饰能力,几乎可以无限制地创造出可能的表达式,搭配stl算法一起演出
bind1st(op,value)
bind2nd(op,value)
not1(op)
not2(op)
when vector
迭代器失效
1)vector重新分配空间
迭代器之配接器
(Interator Adapters)
what 迭代器之配接器:具有迭代器接口,却有着不同的行为
1) Insert iterators
2) Stream iterators
3) Reverse iterator
Insert迭代器 p271
what Inserts迭代器:用来将元素值插入容器内的一种迭代器。用来将“赋值新值”操作转换为“安插新值”操作。通常这种迭代器,算法可以执行安插行为而非覆盖行为。
如果向Inserts迭代器赋予一个元素值,你其实就是将它插入到容器内。如果写入第二个值,并不会覆盖第一个值,而是将值安插进去
int
ia[]={0,1,2,3,4,5};
deque<int> id(ia,ia+6)
copy(ia+1,ia+3,front_inserter(id))
copy(ia+1,ia+3,front_inserter(id))
front_inserter,back_inserter,insert都是用来将容器封装为一个back_insert_iterator<Container>(x)类,内部保存一个容器类x的指针,赋值操作被容器的push_back,push_front,insert等成员函数取代 p271
Inserts迭代器
1)operator*被实作为一个无实际动作的动作(no-op),只是简单传回*this。所以,对Insert迭代器来说,*pos与pos等价
2)递增运算操作符也被实作为一个no-op(无动作)也是简单传回一个*this
3)赋值动作被转化为安插操作。事实上Insert迭代器会调用容器的push_back(),push_front()或insert()成员函数
p274
使用Inserts迭代器时,一定要在调用copy()之前确保有足够大的空间。因为back_inserter在安插元素时,可能会造成容器的其他迭代器失效。因此,如果不保留足够空间,这个算法可能会形成“源端迭代器失效”状态(源空间,和目标空间都是同一容器时)
when使用Inserts迭代器前需注意的问题
1)容器是否支持操作(比如vector不支持push_front,所以不能用front_inserter)
2)调用copy之前要确保有足够大的空间(源空间,和目标空间都是同一容器时)