IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++Primer---C++知识点记录*VI---泛型算法】 -> 正文阅读

[C++知识库]【C++Primer---C++知识点记录*VI---泛型算法】

目录

只读算法

写容器元素的算法

重排容器元素的算法

向算法传递函数

lambda表达式

迭代器

泛型算法结构


标准库并未给每个容器都定义成员函数来实现这些操作,而是定义了一组泛型算法

这些算法并不直接操作容器,而是遍历由两个迭代器指定的一个元素范围

我们发现,它们都可以使用find算法

算法永远不会执行容器的操作。算法运行于迭代器之上,永远不会直接添加或删除元素

只读算法

只读取输入范围内的元素,不改变元素。

例如find,count,accumulate(在头文件numeric)

如accumulate的第三个参数,就是开始累加的初值,这个值便决定了函数中使用哪个+运算符以及返回值的类型。我们只能写string(""),而不能写"",因为const char*上并没有定义+运算符

对于只读而不改变元素的算法,通常最好使用cbegin()和cend(),除非计划使用返回的迭代器去改变元素

除此之外还有equal,前两个参数是一个容器的首迭代器和尾后迭代器,第三参数是另一个的首迭代器。因此这种只接受一个单一迭代器来表示第二个序列的算法,都假定第二个序列至少和第一个一样长

写容器元素的算法

例如,算法fill接受一对迭代器表示一个范围,还接受一个值作为第三个参数,把这个值赋予每个元素。由于算法不会执行容器操作,它不会改变容器大小,因此该算法是安全的

注意,算法不检查写操作

vector<int> vec? ?//空容器

fill_n(vec.begin(),10,0)? //想把前10个元素置0

上边的操作会是灾难性的,因为这是一个空容器!

--------有没有一种保证算法有足够空间来容纳输出数据的方法?----------

【插入迭代器】

插入迭代器是一种向容器中添加元素的迭代器。

值被赋予迭代器指向的元素。

介绍back_inserter(定义在头文件iterator中)

?我们常常使用back_inserter来创建迭代器,作为算法的目的位置来使用

拷贝算法

copy,前两个参数是一组范围,第三个参数是目的序列的起始位置。此算法将输入范围中的元素拷贝到目的序列中

copy返回目的序列中位置迭代器递增后的值

replace(a.begin(),a.end(),0,42)——将所有0都换成42

replace_copy(a.begin(),a.end(),back_inserter(newA),0,42)——原序列不变,newA是原序列的一份拷贝,且所有0都改成了42

重排容器元素的算法

向算法传递函数

例:sort有一个重载的版本,可以接收第3个参数,这个参数叫做谓词

标准库算法有一元谓词(只接受单一参数)、二元谓词(有两个参数)

接受谓词参数的算法对输入序列中的元素调用谓词

stable_sort算法:保持相等元素的原有顺序

lambda表达式

有时,我们希望进行的操作需要更多参数,超出了算法对谓词的限制(谓词就是,比如sort的第三个参数,是二元谓词,传进来的函数必须有两个参数)

lambda表达式是一个可调用对象

[捕获列表] (参数列表) -> return type { function body }

可以省略参数列表和返回类型

?像普通函数的调用一样,调用一个lambda时也要传入实参,且lambda表达式不能用有默认参数

捕获列表是lambda所在函数中定义的局部变量的列表

例:

把find_if中的第三个参数写为这个lambda表达式,就可以解决原来的问题:find_if接受一元谓词,所以我们不能弄一个有两个参数的函数?

现在这样理解:向一个函数传递lambda时,同时定义了一个新类型和该类型的一个对象,传递的参数就是此编译器生成的类类型的未命名对象。

  • ?值捕获
  • 引用捕获
  • 隐式捕获

?↑当我们需要为一个lambda定义返回类型时,就必须使用尾置返回类型

当lambda表达式中有除return语句外的任何语句,编译器就会假定它返回void

参数绑定

对于那种只在一两个地方使用的简单操作,lambda表达式是最有用的。如果我们需要在很多地方使用相同的操作,通常应该定义一个函数,而不是多次编写相同的lambda表达式。同时,如果一个操作需要很多语句才能完成,通常使用函数更好

标准库bind(functional头文件中)

对于这个lambda表达式,能不能用一个函数来替换它呢

?bind接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表

auto newCallable = bind (callable ,arg_list);

arg_list中会有_n这样的占位符,?它们表示newCallable中的参数,例如_1为newCallable中的第一个参数

上图这种情况,会调用check_size(s,6)

因此,可以把之前的lambda表达式换成函数check_size版本了

?

?加深理解:

绑定引用参数:

bind(....ref(os),....)因为bind是拷贝其参数,而我们又不能拷贝一个ostream

迭代器

除了为每个容器定义的迭代器,标准库还在头文件iterator中定义了额外几种迭代器

  • 插入迭代器:被绑定到一个容器上,可以用来向容器插入元素
  • 流迭代器:被绑定到输入输出流上,可用来遍历所关联的io流
  • 反向迭代器:向后而不是向前移动,除了forward_list之外的标准库容器都有反向迭代器
  • 移动迭代器:不是拷贝其中的元素,而是移动它们

I-插入迭代器

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

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

inserter创建一个使用insert的迭代器

其它:p359-364待学

5类迭代器p366

泛型算法结构

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 10:32:27  更:2022-07-03 10:35:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/11 18:36:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码