本文主要是介绍16 适配器,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
adapter 适配器
- 迭代器适配器 与算法合作 迭代器的5 个typedef
- 容器适配器 : stack, queue, map, set, multimap, multiset, unordered_set, unordered_multiset, unordered_map, unordered_multimap
- 仿函数适配器 与算法合作
设计模式:adapter
适配器的实现
a -> b
- 继承方式 (不使用)
- 组合方式 yes
容器适配器
容器适配器:stack, queue
内含一个sequence: deque
函数适配器
何时绑定?调用时绑定。第二个参数类型如何确定?通过辅助模版函数类型推导获得
() 到底是函数调用? 还是在创建对象?
把东西记起来,等着以后调用
cout << count_if(vec.begin(), vec.end(), not1(bind2nd(less<int>() , 40))) <<endl;
binder2nd
- Bind2nd 将第二个参数绑定为指定的参数, less () 是一个对象,传给bind2nd,
- 40也传给了bind2nd,并且依靠辅助函数进行类型推导。binder2nd
- Bind2nd 修饰functor,修饰之后也要表现为functor
- 在被调用的时候才有绑定第二个参数的动作发生。
- binder2nd是个类模版-》主体,因为模版参数是Operation
- 对外界的接口是bind2nd 函数模版可以做参数推导,获得op类型和x的类型 Operation, T
- 这两个参数传给构造函数,将x记录在op中,y记录在value中。生成对象。传给count_if使用
细节:
- 灰色部分:问和答
- arg2_type 是什么类型 arg2_type(x) 在编译时通过表示可以转换,如果不能通过则编译时错误,而不是runtime-error
- 返回的是什么类型? Typename Operation::result_type
- 第一个实参是什么类型? const typename Operation::first_argument_type
- 为什么要加上typename? 帮助编译器通过这行代码是不应该通过的,让编译器能通过
- 继承的typedef
- 如果binder2nd 也想要被适配的话,也要继承unary_function,才能回答两个问题:实参和返回类型
已经被bind取代了
not1
bind
bind 的实现相当的复杂。
Std::bind 可以绑定:
- 函数
- 仿函数
- 成员函数
- 类数据成员
使用占位符:using namespace std::placeholders
对象后面 {} 赋初值
绑定第一个参数是成员函数,由于成员函数有一个隐藏的this指针,需要将对象传入以获得正确的this指针,所以用占位 _1来占位,真正调用bind的时候将对象传进去
迭代器适配器
在排序的时候使用过,实现的时候要注意不要越界。
排序默认是less ,但是传入的迭代器是逆向的,那么输出的就是降序排列
reverse_iterator 操作符重载
- 逆向迭代器的5种typedef与正向迭代器相同
- 对逆向求值就是对正向退一步求值
- 先看对象重载解引用操作符: 先–,再解引用
- 后置改为前置
inserter 操作符重载
- 当容器size不足时,copy可能会导致溢出,因为copy不会考虑目的空间是否足够
- inserter 会负责insert操作,并且将iterator 右移一个位置,这样就可以连续执行表面上assign实际上insert的行为
- 在3,4中间,插入元素。copy中的代码已经写好,不能变了,将目的端迭代器改为inserter
源码:
inserter辅助函数 进行类型推导。
assign 操作符重载,改变行为
- 先调用容器的插入算法,返回插入的位置给 iter
- ++iter使得ite指向刚插入的元素位置
- 返回给调用者,可以继续进行插入操作。
X 适配器 ostream_iterator 重载了什么?
- 第一个参数绑定了cout, 第二个参数传入字符串作为分隔符。
- copy的源代码是固定的,因为有操作符重载,所以行为不同。
- 解引用,
- 赋值。
- ++
- 最后返回,会调用拷贝构造函数
- 这些动作最后能传给cout中
源码
- 构造函数,观察传进去的值是啥: s, dilimiter
- 解引用操作符,返回自身的引用
- 赋值运算符
- *out_stream << value;
- 如果占位符不为空,*out_stream << delimiter;
- return *this; cout是全局对象,只有一个。
- 前置,后置++ 返回自身的引用
- 对out_stream迭代器改造:将字符串输出到屏幕上
X 适配器: stream_iterator 做了些什么
- eos表示输入状态结束了
iit
调用的有参数构造函数
- 构造过程中++
- ++运算符重载:等待输入 阻塞
- != 运算符
- 解引用操作符重载: 将读取成功的值返回
- ++iit 再读一次,阻塞等待键盘输入
- input 是 basic_istream 可以是cin 也可以是文件等
- 对迭代器不断++相当于不断读内容
与copy一起使用
必须定义操作符,来适配已经写好的copy的动作
- 在创建iit对象的时候就开始读输入
- !=
-
- ++
- return 引发的拷贝构造函数
意义和价值
- 6大部件的实现
- 数据结构
- 模版在使用的时候,一旦用错了,会报出很多的错误信息,读源码有利于使用STL
这篇关于16 适配器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!