点击查看Evernote原文

#@author:       gr
#@date: 2014-08-24
#@email: forgerui@gmail.com

STL中的适配器。

###stl学习

 |--迭代器

 |--类属算法

 |--容器

   |--vector

   |--deque

   |--list

   |--set

   |--map

 |--函数对象

 |--适配器

 |--分配器

一、Contents

适配器概述:

适配器作用是改变其他组件的接口。它们是以模板类的形式定义的,并且以另一种组件的类型作为参数。STL提供了3种适配器组件,包括容器适配器迭代适配器函数适配器


容器适配器

1. 栈容器适配器(stack)

栈适配器只有有限的接口,包括push,pop,top,empty,size。可以用vector,deque,list实现。其中pop函数没有返回值,要取值,先用top函数获取。

stack是类型为T的栈,默认情况下以deque实现。

stack< T, vector >是类型为T的栈,以vector实现。

stack< T, list >是类型为T的栈,以list实现。

stack< T, deque >是类型为T的栈,以deque实现。

stack<int> s;
int thedata[] = {1, 2, 3, 4};
for (int i = 0; i < 4; i++){
s.push(thedata[i]);
}
s.pop();
cout<<s.top();
cout<<s.size();
while (!s.empty())
s.pop();

2. 队列适配器(queue)

queue提供的操作包括:empty,size,front,back,push,pop。同样,pop没有返回值。队列适配器可以使用listdeque实现。没有vector,因为它不支持pop_front,实际上实现pop_front很容易,v.erase(v.begin());便可以,但是这个操作需要将后面所有值都前移,效率太低,没有vector没有提供这种接口。

queue类型为T的队列,默认情况下以deque实现。

queue<T, list >类型为T的队列,以list实现。

queue<T, deque >类型为T的队列,以deque实现。

int thedata[] = {1, 2, 3, 4};
//使用list实现
queue<int, list<int> > q;
for (int i = 0; i < 4; i++){
q.push(the_data[i]);
}
q.pop();

3. 优先级队列容器适配器

优先级队列根据元素之间某种特定的排序准则,只有序列中最大的元素可以第一个被检索到。可以用具有随机访问迭代器的容器实现,即可以使用vectorlist实现。

priority_queueint类型保存到vector中,并使用默认的比较对象less<int>

priority_queue<int, list, greater >int类型保存到list中,并使用greater<int>比较对象。

priority_queue<int, vector, greater >int类型保存到vecotr中,并使用greater<int>比较对象。

int thedata[] = {1, 2, 3, 4};
//使用默认
priority_queue<int> pq;
for (int i = 0; i < 4; i++){
pq.push(the_data[i]);
}
pq.pop();

迭代器适配器

1. 反向迭代器适配器

迭代器适配器是用来改变迭代器组件的STL组件。STL中只预定了这一种迭代器适配器。容器都直接提供了反向迭代器,reverse_iteratorconst_inverse_iterator,也可以使用rbeginrend

使用accumulate进行浮点数相加时,如果是从大到小排序,则一般相加是从大到小相加,然而我们知道,先将小数进行相加,可以获得更高的准确率,一个例子中,从左向右结果为1,而从右向左(小数先加)的结果为1.000000119,得到的结果更加精确。

float sum1 = accumulate(v.begin(), v.end(), (float)0.0);
float sum2 = accumulate(v.rbegin(), v.rend(), (float)0.0);
//使用反向迭代器,从后往前遍历
vector<char>::reverse_iterator r = find(v.rbegin(), v.rend(), 't');
//从后往前拷贝
copy(r, v.rend(), out);

函数适配器

函数适配器可以帮助我们创建各类更加广泛的函数对象。STL提供了3种类型函数适配器:绑定器(binder),取反器(negator)和函数指针适配器。

1. 绑定器

可以把二元函数的一个参数绑定到一个特定的值,将二元函数转化为一元函数。

//可以使用bind1st去绑定第一个参数,下面程序的功能是查找第一个>200元素位置
int* where = find_if(&arr[0], &arr[100], bind2nd(greater<int>(), 200));
//greater operator()定义
bool operator() (int x, int y) const { return x > y;}
//使用bind2nd后可以理解为
bool operator() (intx) const { return x > 200;}

2. 取反器

取反器是一种用来对判决函数对象取反的函数适配器。STL提供了两种类型的取反适配器,not1not2

not1是对一元判决函数取反,not2是对二元判决函数取反。

//查找第一个不大于200(即<=200)的元素
int* where = find_if(&arr[0], &arr[100], not1(bind2nd(greater<int>(), 200)));
//上面也可以直接用函数对象less_equal实现,更明确
int* where = find_if(&arr[0], &arr[100], bind2nd(less_equal<int>(), 200));

3. 函数指针适配器

提供函数指针适配器的目的是为了让指向一元二元函数的指针能够与STL所提供的其它函数适配器一起工作。

如果在一个程序中需要使用两种不同的集合,但它们只有比较函数不同,如下定义:

set<string, less<string> > set11;
set<string, greater<string> > set2;

尽管两个实体的大部分实现代码都相同,编译器还是会重复生成两个实体的大部分或全部实现代码,为了避免这种代码重复,可以只声明set的一个实体,并使用函数指针适配器作为其比较函数的类型,用来保持集合中元素的有序性。

set<string, pointer_to_binary_function<const string&, const string&, bool> >

具体实现需要合用ptr_fun:

bool less1(const string& x, const string& y){
return x < y;
}
bool greater1(const string& x, const string& y){
return x > y;
}
int main(){
typedef set<string, pointer_to_binary_function<const string&, const string&, bool> > set_type1 set_type1 set1(ptr_fun(less1));
//可以使用set1了
set1.insert("the");
set_type1 set2(ptr_fun(greater1));
//可以使用set2了
set2.inser("the");
}

这种操作利用函数指针需要直接寻址,比使用不同的set实体的程序慢一点,但这种方式可以大大降低可执行文件大小。

二、Miscellany

@author gr
@mail forgerui@gmail.com

###STL学习--适配器的更多相关文章

  1. 侯捷STL学习(11)--算仿+仿函数+适配器

    layout: post title: 侯捷STL学习(十一) date: 2017-07-24 tag: 侯捷STL --- 第三讲 标准库内核分析-算法 标准库算法形式 iterator分类 不同 ...

  2. ###STL学习--vector

    点击查看Evernote原文. #@author: gr #@date: 2014-08-11 #@email: forgerui@gmail.com vector的相关问题.<stl学习> ...

  3. ###STL学习--关联容器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的关联容器. ###stl学习 |--迭 ...

  4. ###STL学习--迭代器

    点击查看Evernote原文. #@author: gr #@date: 2014-08-23 #@email: forgerui@gmail.com STL中的迭代器. ###stl学习 |--迭代 ...

  5. ###STL学习--函数对象

    点击查看Evernote原文. #@author: gr #@date: 2014-08-13 #@email: forgerui@gmail.com 在stl中,函数对象被大量地使用,用以提高代码的 ...

  6. 标准模板库(STL)学习探究之stack

    标准模板库(STL)学习探究之stack queue priority_queue list map/multimap dequeue string

  7. 标准模板库(STL)学习探究之vector容器

    标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...

  8. STL学习:STL库vector、string、set、map用法

    本文仅介绍了如何使用它们常用的方法. vector 1.可随机访问,可在尾部插入元素:2.内存自动管理:3.头文件#include <vector> 1.创建vector对象 一维: (1 ...

  9. Effective STL 学习笔记 39 ~ 41

    Effective STL 学习笔记 39 ~ 41 */--> div.org-src-container { font-size: 85%; font-family: monospace; ...

随机推荐

  1. iframe中的各种跳转方法

    iframe中的各种跳转方法(转)   一.背景A,B,C,D都是jsp,D是C的iframe,C是B的iframe,B是A的iframe,在D中跳转页面的写法区别如下. 二.JS跳转window.l ...

  2. 常用 Unicode 符号列表

    Unicode 中包含了各种符号,我们可以作为图标来使用.这里整理一下常用的一些符号. 一.拉丁字母补全(Latin-1 Supplement):U+0080 至 U+00FF Unicode 编号 ...

  3. Java中方法的重载

    Java 中方法的重载 问: 什么是方法的重载呢? 答: 如果同一个类中包含了两个或两个以上方法名相同.方法参数的个数.顺序或类型不同的方法,则称为方法的重载,也可称该方法被重载了.如下所示 4 个方 ...

  4. UITabBarController详解

    UITabBarController使用详解 UITabBarController是IOS中很常用的一个viewController,例如系统的闹钟程序,ipod程序等.UITabBarControl ...

  5. hdu 5497 Inversion 树状数组 逆序对,单点修改

    Inversion Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5497 ...

  6. Matlab画图-非常具体,非常全面

    Matlab画图 强大的画图功能是Matlab的特点之中的一个,Matlab提供了一系列的画图函数,用户不须要过多的考虑画图的细节,仅仅须要给出一些基本參数就能得到所需图形,这类函数称为高层画图函数. ...

  7. Tomcat 集群

    1.  前言 该篇中测试的机器发生了变更,在第一篇中设置的Apache  DocumentRoot "d:/deployment"修改为了DocumentRoot d:/clust ...

  8. zend studio 安装xdebug

    XDebug安装 到http://xdebug.org/download.php选择自己需要的xdebug版本.然后按照下面的配置建立目录.并在php.ini加入这些内容.重启server 注意xde ...

  9. Linux-PAM(Linux下的密碼認證和安全机制)系統管理員指南(中文版)

    he Linux-PAM 系统管理员指南作者:Andrew G. Morgan, morgan@linux.kernel.org翻译:孙国清(Thomas Sun),thomassun@yeah.ne ...

  10. 六、Socket之UDP异步传输文件-实现稳定的文件传输

    上一篇文章五.Socket之UDP异步传输文件-实现传输中取消传送中,还遗留了一个传输文件最大的问题,就是传输过程中丢包,这样在文件传输过程中就会卡住了,这篇文章就来解决文件传输中的丢包问题,实现稳定 ...