C++ primer 第十章复习(2)

简介: C++ primer 第十章复习

10.4 再探迭代器


插入迭代器有三种类型:


back_inserter,创建一个使用 push_back 的迭代器


front_inserter 创建一个使用 push_front 的迭代器


inserter 创建一个使用 insert 的迭代器,插入迭代器之前的位置

/*
  it是由inserter生成的迭代器
*/
std::vector<int> vec1;
int val =42;
auto it = std::inserter(vec1,vec1.begin()); 
*it =42; //其效果与下面代码一致
auto it = vec1.insert(vec1.begin(), 42);//it指向新插入的元素
++it;//递增it使它指向原来的元素
std::list<int> lst = { 1, 2, 3, 4 };
std::list<int> lst2, lst3;//空
//拷贝完成后,lst2 包含 4,3,2,1
std::copy(lst.cbegin(), lst.cend(), std::front_inserter(lst2));
//拷贝完成后,lst2 包含 1,2,3,4
std::copy(lst.cbegin(), lst.cend(), std::inserter(lst3,lst3.begin()));

IOStream 迭代器


将它们对应的流,当做一个特定类型的元素序列来处理



std::istream_iterator<int> int_iter(std::cin); //绑定一个流,从cin读取int
  std::istream_iterator<int> eof; //默认初始化迭代器,尾后迭代器
  std::vector<int> vec;
while (int_iter != eof){
    //后置递增运算读取流,返回迭代器的旧值
    //解引用迭代器,获得从流读取的前一个值
    vec.push_back(*int_iter++);
  }
}
//元素范围是通过关联的流中读取数据获得的,这个构造函数从cin中读取数据,
//直至遇到文件尾或者遇到一个不是int的数据为止
std::istream_iterator<int> int_iter(std::cin),eof;
std::vector<int> vec(int_iter, eof);
//#include <fstream>std::ifstream in("file");
std::istream_iterator<std::string> str_it(in); //从in读取字符串

使用算法操作流迭代器


std::istream_iterator<int> int_iter(std::cin), eof;
std::cout << std::accumulate(int_iter, eof, 0) << std::endl;
//此调用计算从标准输入读取的值之和
//如果输入 125,则输出 8

//使用ostream_iterator来输出值的序列
std::ostream_iterator<int> out_iter(std::cout," ");
std::vector<int> vec;
for (auto e : vec){
  *out_iter++= e; //赋值语句实际上将元素写到cout
  //运算符++和*对ostream_iterator不做任何事
}
std::cout << std::endl;
//用out_iter时,可忽略解引用和递增
for (auto e : vec){
  out_iter = e; //赋值语句实际上将元素写到cout
}
std::cout << std::endl;
std::copy(vec.begin(), vec.end(), out_iter);
std::cout << std::endl;

使用迭代器处理类类型



反向迭代器


反向迭代器需要递减运算符,所以 forward_list 或流迭代器不能创建反向迭代器



std::vector<int> vec = { 0, 1, 2, 3, 4 };
//从尾元素到首元素的方向迭代器
for (auto r_iter = vec.crbegin(); r_iter != vec.crend(); ++r_iter){
  std::cout << *r_iter << std::endl;
}
std::sort(vec.begin(), vec.end()); //正常序列,升序
std::sort(vec.rbegin(), vec.rend()); //逆序排序


std::string line ="first,middle,last";
//在逗号分隔的列表中查找第一个元素
auto comma = std::find(line.cbegin(), line.cend(), ',');
std::cout << std::string(line.cbegin(), comma) << std::endl;
//在第一逗号分隔的列表中查找最后一个元素
auto rcomma = std::find(line.crbegin(), line.crend(), ',');
//错误,将逆序输出单词的字符
std::cout << std::string(line.crbegin(), rcomma) << std::endl;
//正确 : 将得到一个正向迭代器,从逗号开始读取字符直至line末尾
std::cout << std::string(rcomma.base, line.cend()) << std::endl;

10.5 泛型算法结构

算法最基本的特性是它要求迭代器提供哪些操作



类似容器,迭代器的操作也是有层次的,高层类别的迭代器支持所有底层类别迭代器操作,例如:


ostream_iterator 只支持递增,解引用和赋值


vector,string,deque 的迭代器还支持递减,关系和算术运算


C++ 标准指明了算法的每个迭代器参数的最小类别:例如,replace_copy 的前两个迭代器至少是向前迭代器,第三个至少是输出迭代器


算法形参模式


大多数算法具有如下四种形式之一 :


算法命名和重载规范





10.6 特定容器算法

对于 list 和 forward_list ,应该优先使用成员函数版本的算法,而不是通用算法







相关文章
|
6月前
|
编译器 C++
c++primer plus 6 读书笔记 第十章 对象和类
c++primer plus 6 读书笔记 第十章 对象和类
|
6月前
|
编译器 数据安全/隐私保护 C++
c++primer plus 6 读书笔记 第十三章 类继承
c++primer plus 6 读书笔记 第十三章 类继承
|
6月前
|
C++
C++ Primer Plus (第6版)中文版 (使用XMind整理)
C++ Primer Plus (第6版)中文版 (使用XMind整理)
C++ Primer Plus (第6版)中文版 (使用XMind整理)
|
6月前
|
C++
c++primer plus 6 读书笔记 第十四章 C++中的代码重用
c++primer plus 6 读书笔记 第十四章 C++中的代码重用
|
6月前
|
C++
c++primer plus 6 读书笔记 第十一章 使用类
c++primer plus 6 读书笔记 第十一章 使用类
|
6月前
|
编译器 C++
c++primer plus 6 读书笔记 第八章 函数探幽0
c++primer plus 6 读书笔记 第八章 函数探幽0
|
6月前
|
编译器 vr&ar C++
c++primer plus 6 读书笔记 第七章 函数--C++的编程模块
c++primer plus 6 读书笔记 第七章 函数--C++的编程模块
|
6月前
|
SQL 人工智能 算法
技术心得记录:模板函数函数模板FunctionTemplate(C++Primer
技术心得记录:模板函数函数模板FunctionTemplate(C++Primer
|
6月前
|
程序员 C++
c++primer plus 6 读书笔记 第十二章 类和动态内存分配
c++primer plus 6 读书笔记 第十二章 类和动态内存分配
|
6月前
|
存储 IDE 编译器
c++primer plus 6 读书笔记 第九章 内存模型和名称空间
c++primer plus 6 读书笔记 第九章 内存模型和名称空间