《C++ Primer》读书笔记第十章-2-再探迭代器 And 泛型算法结构
2017-09-20 11:47
363 查看
笔记会持续更新,有错误的地方欢迎指正,谢谢!
插入迭代器:绑定到容器上,可用来向容器中插入元素。
流(iostream)迭代器:绑定到输入输出流上,可用来遍历所关联的IO流。
反向迭代器:跟普通的迭代器方向相反(forward_list没有这个,你懂得)。
移动迭代器:是移动元素而不是拷贝元素(是不是很诱人~以后再详细介绍)。
back_inserter, inserter,front_inserter
插入迭代器:back_inserter、inserter、front_inserter分别调用容器操作push_back、insert、push_front。
流迭代器将它们对应的流当作一个特定类型的元素序列(类似容器)来处理。通过使用流迭代器,我们可以使用泛型算法从流对象读取数据以及向其写入数据 。
下面是一个用istream_iterator从标准输入读取数据,存入一个vector的例子:
我们来个牛逼的写法:
这两行代码和上面的程序完全等价:我们用一对元素范围的迭代器来构造vec,这个构造函数通过in_iter从cin中读取数据,直到遇到文件尾或者遇到不是int的数据为止,从流中读取的数据用于构造vec。
再来个酷炫的,输入数据求和:
补充:如果两个istream_iterator都是尾后迭代器或绑定到相同的输入则相等。
使用反向迭代器的时候,要注意的就是+ +和- -时的前进方向。
不懂的看下图:
函数说明:
splice成员:链表特有的算法,将一个链表的一截移动到另一个链表的指定位置,要保证移动的目的位置不在待移动范围内
再探迭代器
除了前面介绍的标准库容器迭代器外,C++还在头文件iterator中定义了额外的集中迭代器:插入迭代器:绑定到容器上,可用来向容器中插入元素。
流(iostream)迭代器:绑定到输入输出流上,可用来遍历所关联的IO流。
反向迭代器:跟普通的迭代器方向相反(forward_list没有这个,你懂得)。
移动迭代器:是移动元素而不是拷贝元素(是不是很诱人~以后再详细介绍)。
插入迭代器
有三种:back_inserter, inserter,front_inserter
插入迭代器:back_inserter、inserter、front_inserter分别调用容器操作push_back、insert、push_front。
vector<int> vec; auto it = back_inserter(vec); *it = 0; //{0},尾插 auto is = front_inserter(vec); *is = -1; //{-1, 0},头插 list<int> lst1 = {1, 2, 3}; list<int> lst2; copy(lis1.cbegin(), lst1.cend(), inserter(lst2, lst2.begin()) ); //lst2拷贝了lst1
流迭代器
虽然iostream不是容器,但标准库还是定义了这些类型对象的迭代器。istream_iterator读取输入流,ostream_iterator向一个输出流写数据。流迭代器将它们对应的流当作一个特定类型的元素序列(类似容器)来处理。通过使用流迭代器,我们可以使用泛型算法从流对象读取数据以及向其写入数据 。
下面是一个用istream_iterator从标准输入读取数据,存入一个vector的例子:
istream_iterator<int> in_iter(cin); //从cin读取int istream_iterator<int> eof; //空的istream_iterator当作istream尾后迭代器 while(in_iter != eof) { vec.push_back(*in_iter++);//先对in_iter解引用后,最后才把in_inter自增1。 }
我们来个牛逼的写法:
istream_iterator<int> in_iter(cin), eof; vector<int> vec(in_iter, eof);
这两行代码和上面的程序完全等价:我们用一对元素范围的迭代器来构造vec,这个构造函数通过in_iter从cin中读取数据,直到遇到文件尾或者遇到不是int的数据为止,从流中读取的数据用于构造vec。
再来个酷炫的,输入数据求和:
istream_iterator<int> in(cin), eof; cout << accumulate(in, eof, 0) << endl; //从标准输入中读取数值求和输出
补充:如果两个istream_iterator都是尾后迭代器或绑定到相同的输入则相等。
反向迭代器
来个例子,逆序打印vec中的元素:vector<int> vec = {1, 2, 3}; for(auto r_iter = vec.crbegin(); r_iter != vec.crend(); ++r_iter) { cout << *r_iter << endl; }
使用反向迭代器的时候,要注意的就是+ +和- -时的前进方向。
不懂的看下图:
泛型算法结构
都是对之前一些细节的总结,就不说了,没什么实质内容。特定容器算法-链表list和forward_list
与其他容器不同,链表定义了独有的一些函数:sort(), merge(), remove(), reverse()和unique(),可改变底层容器,优先使用它们而不是通用算法。因为通用的sort()要求随机访问迭代器,因此不能用于链表,链表要用双向迭代器或前向迭代器。函数说明:
函数 | 含义 |
---|---|
lst.merge(lst2)(重载版:lst.merge(lst, comp)) | 将lst2的元素并入lst中,二者原先必须是有序的。第一个版本使用的是<运算符;第二个版本使用自定义比较操作。合并后,lst2变为空。 |
lst.remove(val)(重载版:lst.remove_if(pred)) | 函数会调用erase()删除与val相等或使一元谓词pred为真的所有元素。 |
lst.reverse() | 翻转lst的元素顺序。 |
lst.sort()(重载版:lst.sort(comp)) | 使用<或自定义比较操作排序元素。 |
lst.unique()(重载版:lst.unique(pred)) | 调用erase()删除同一个值的连续拷贝。第一个版本使用==,第二个版本使用给定的二元谓词 |
相关文章推荐
- 《C++ Primer》读书笔记第十章-1-初识泛型算法 And Lambda
- C++ Primer :第十章 :泛型算法之再探迭代器以及其他算法
- C++ Primer 学习笔记_45_STL实践与分析(19)--泛型算法的结构
- C++ Primer : 第十章 : 泛型算法 之 只读、写和排序算法
- C++ Primer : 第十章 : 泛型算法 之 lambda表达式和bind函数
- c++ primer(第五版)笔记 第十章 泛型算法(3)
- c++ primer(第五版)笔记 第十章 泛型算法(4)
- C++ Primer (第十章:泛型算法)
- C++ Primer 学习笔记:泛型算法入门 插入迭代器 && iostream迭代器 && 反向迭代器
- 实验测试1《C++ Primer》第五版——第十章 泛型算法
- c++ primer(第五版)笔记 第十章 泛型算法(1)
- C++STL总结(附带容器迭代器泛型算法详情链接【未完成】)
- 《C++ Primer》读书笔记第二章-1-基本内置类型 And 变量
- C++学习笔记【第二部分第十章:泛型算法】
- 《c++ primer》第10章 泛型算法 学习笔记
- C++语法基础--泛型算法(generic algorithm)--iostream迭代器
- C++语法基础--泛型算法(generic algorithm)--反向迭代器,reverse_iterator::base()
- 泛型算法结构
- [读书笔记]C#学习笔记四: C#2.0泛型 可控类型 匿名方法和迭代器
- 迭代器学习之三:IEnumerable和IEnumerator的泛型结构