STL分析(九 适配器)

news2024/11/15 17:51:36

容器适配器:stack,queue

在这里插入图片描述
stack和queue内含一个deque

函数适配器

binder2nd绑定第二参数

在这里插入图片描述

  1. 调用的过程中,算法count_if函数读取了迭代器头尾指针后,读取第三个参数为functor
    object即仿函数。因此在其参数为bind2nd(less< int>(),40)时首先要为bind2nd类构造一个对象。
  2. 在模板类bind2nd中传入的op为Operation泛型类型,编译器可在传入实参时自动推导Operation类型,并在后面返回调用构造binder2nd对象时用推导出的Operation类型构造binder2nd对象。
  3. 调用binder2nd构造函数时将less< int>()临时对象交给op成员,绑定的第二个参数40交给value成员。binder2nd由于已经被绑定了一个操作数,因此继承unary_function,只有一个参数。在binder2nd中,内含了一个Operation类型functor和一个以该functor第二参数为类型的第二参数value。由于调用的函数对象less< int>()等一般有两个操作数,其继承自binary_function。由于后面这个binder2nd函数对象要调用()来调用内涵的Operation function,因此其需要重载()操作符,并以Operation function的result_type作为返回类型。
  4. 回到count_if函数调用时,对第三个参数即仿函数对象调用pred(*first);,此时构造函数已经返回binder2nd对象,实质上是用重载()调用刚刚构造好的binder2nd对象,并return回Operation functor的调用,即less<int>(*first, value);

not1

template <class Predicate>
inline unary_negate<Predicate> not1(const Predicate& pred){
    return unary_negate<Predicate>(pred);
}
 
template <class Predicate>
class unary_negate
    : public unary_function<typename Predicate::argument_type, bool>{
protected:
    Predicate pred;
public:
    explicit unary_negate(const Predicate& x) : pred(x) {}
    bool operator()(const typename Predicate::argument_type& x) const{
        return !pred(x);
    }
};

在被上面的count_if()函数调用时,not1函数对象调用operator()返回里面的相反条件。

bind

在C++11后,bind1st,bind2nd等被bind取代。bind可以绑定四种东西(1)函数与仿函数(2)类的成员函数及数据成员,其中_1必须是某个object的地址
第一种:

double my_divide (double x, double y)
    { return x / y; }
 
//bind的使用示例
auto fn_five = bind(my_divide, 10, 2);               //fn_five() return 10/2
 
auto fn_half = bind(my_divide, _1, 2);               //fn_half(x) return x/2
 
auto fn_invert = bind(my_divide, _2, _1);            //fn_invert(x, y) return y/x
 
auto fn_rounding = bind<int> (my_divide, _1, _2);    //fn_rounding(x, y) return (int)x/y

其中_n为占位符,意思是实际调用第n个参数。如第三个例子_2为第二个参数y,_1位第一个参数x,在后面调用fn_invert(x, y)即可以实现参数互换

第二种:

struct MyPair{
    double a, b;
    double multiply() { return a * b; }
        //member function其实有个argument:this
};
 
 
//binding类的成员的示例
MyPair ten_two {10, 2};
 
auto bound_memfn = bind(&MyPair::multiply(), _1);
    //bound_memfn(x) return x.multiply()
 
auto bound_memdata = bind(&MyPair::a, ten_two);
    //bound_memdata() return tem_two.a
 
auto bound_memdata2 = bind(&MyPair::b, _1);
    //bound_memdata2(x) return x.b

可以看出bind可以实现绑定类的成员,无论是数据成员还是函数成员,bind需要传入成员指针,它的_1始终表示对象的this指针,当不指定具体传入的对象时,调用bind后的结果时就需要传入一个object,有点像一个隐藏参数。

迭代器适配器

reverse_iterator

以看出逆向迭代器需要满足两个行为:(1)正确地引用元素值。(2)方向和原来相反。以rbegin()为例,它的值按理来说和end()是完全相同的,但是指向的元素一个在前一个在后。以下是逆向迭代器的源码,从运算符重载函数可以看出以上两个行为的体现:

在这里插入图片描述

inserter

我们知道标准库的copy()函数格式为:copy( begin(), end(), result() ),将会在目的端进行元素的拷贝赋值,那么如果我们想在目的端做插入赋值该怎么办?答案是使用inserter(),所以copy()函数就可以写成这样:copy( begin(), end(), inserter(container, result()) )
在这里插入图片描述
可以看到inserter中也采用了用inserter主函数推导了模板实参Container和Container::iter
的类型后调用次函数insert_iterator。在次函数中实现了操作符=的重载,在调用*result = *first;时调用operator=()重载,对result迭代器指向的地方做insert()操作,再将insert_iterator同步到insert()返回的指针的后一位,即下一个target上。
注意:insert_iterator的重载的++运算符操作并不做任何事情,只是return *this,因此++iter;的操作必须在operator=()中实现,以移动target指针

ostream和istream的适配器

ostream_iterator

在这里插入图片描述
观察构造函数看到,ostream_iterator接收一个basic_ostream和一个分隔符,通过对operator=的重载,将赋值运算符定义为往basic_ostream里面放东西,以此达到输出值的效果。
注意:operator * (),operator++(),operator++(int)什么都不做,只是return *this;,和传统迭代器不同

istream_iterator

在这里插入图片描述
可以看到istream_iterator是通过重载operator++()来输入元素的,且在创建一个istream_iterator对象时,就会自动调用operator++(),等待一个数值的输入。若创建一个无参数的istream_iterator,其内部指针in_stream会被置为0,用来标志输入结束。

下面是一个copy函数调用istream_iterator的例子
在这里插入图片描述
在第一次创建istream_iterator对象时,已经输入了一个数值在对象的value成员中,调用*返回value成员,进行对inserter()函数返回的对象赋值,后面将inserter()对象++后再讲istream_iterator++,输入第二个数值,在下一轮赋给inserter()对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/176277.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode220123_140、117. 填充每个节点的下一个右侧节点指针 II

给定一个二叉树struct Node {int val;Node *left;Node *right;Node *next;}填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL。初始状态下&#xff0c;所有 next 指针都被设置为 NULL。进阶…

双指针思想,c语言

问题导入 对一个给定的自然数M&#xff0c;求出所有的连续的自然数段&#xff0c;这些连续的自然数段中的全部数之和为M。 例如&#xff1a;1998 1999 2000 2001 2002 10000&#xff0c;所以从1998到2002的一个自然数段为M 10000的一个解。 输入格式 第一行&#xff0…

JQuery总结(三)

jQuery 事件 on可以同时绑定多个事件&#xff0c;并且动态添加的元素也会自动添加事件 自动触发事件&#xff1a; 案例1&#xff1a; <style>div{width: 100px;height: 200px;background-color: violet;transition: all .5s;}.current{width: 200px;height: 100px;ba…

ARP渗透与攻防(三)之流量分析

ARP攻击-流量分析 ARP渗透与攻防(一)之ARP原理 ARP渗透与攻防(二)之断网攻击 系列文章 1.环境准备 1.kali作为攻击机 2.win10作为靶机 IP地址&#xff1a;192.168.110.11 3.网关 IP地址&#xff1a;192.168.110.1 2.kali数据包转发 出于安全考虑&#xff0c;Linux系统默…

使用Py6S计算瑞利反射率教程

1、前言那么&#xff0c;首先&#xff0c;什么是瑞利反射率&#xff1f; 好吧&#xff0c;这是由大气中的瑞利散射引起的反射率&#xff08;在大气层顶部测量&#xff09;。 这是大气中气体分子对光的波长依赖性散射——这是光穿过大气时不可避免的结果。所以&#xff0c;关于如…

【2022年度总结与2023展望】---22年故事不长,且听我来讲

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f4e3;系列专栏&#xff1a;故事 文章目录前言一、高考前及高考后的暑假二、大一上的生活2.1 感受校园美景2.2 进入ACM实验室2.3 比赛和比赛经历三、那些帮助过我的人…

AlmaLinux 9 安装Oracle GraalVM Enterprise Edition 22.3.x

今天我们尝试一下在AlmaLinux 9 安装Oracle GraalVM Enterprise Edition 22.3.x。 GraalVM Enterprise 22是包含新功能的最新版本&#xff0c;但不是Long-Term-Support (LTS) 版本。 注意&#xff1a;下载Oracle GraalVM Enterprise Edition需要有Oracle账户&#xff0c;如果没…

六、pyhon操作mysql篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. 下载pymysql 2. 新建数据库 3. mysql服务器版本查询 4. 执行非查询性质的SQL 5. 执行查询性质的sql ​​​​​​​6. 执行新增sql 1. 下载pymysql 右下角点击版本 选择解释器设…

基于Markdown文件的个人wiki

节后第一更&#xff0c;老苏祝您兔年大吉&#xff0c;幸福安康&#xff0c;事事顺心&#xff01; 什么是 wikmd &#xff1f; wikmd 是一个基于文件的 wiki&#xff0c;旨在简化。这些文档完全用 Markdown 编写&#xff0c;使用 pandoc 将 Markdown 文件转换为 html5。 &#…

WPF__Viewport3D 学习记录

1、相机的摆放位置和姿态 Position 是指定照相机的位置&#xff0c;注意Z轴的坐标&#xff0c;如果Z轴值大于模型的Z轴值&#xff0c;那么镜头就在物体前面&#xff0c;反之在物体后面。因此&#xff0c;你可以设置 LookDirection 来调整相机的方向&#xff0c;Position是相机的…

NodeJS 之模块化

NodeJS 之模块化参考描述模块化优点分类加载模块作用域优点自定义模块modulemodule.exportsexports 与 module.exports示例示例一示例二示例三建议CommonJS规范CommonJS参考 项目参考搜索引擎Bing哔哩哔哩黑马程序员 描述 项目描述操作系统Windows 10 专业版NodeJS18.13.0 模…

MU-MIMO是什么

欢迎来到东用知识小课堂&#xff01;1.什么是MIMOMIMO&#xff1a;Multiple-Intput Multiple-Output,即多入多出系统&#xff0c;这里的入和出是相对于发射天线和接受天线构成的天线系统来讲。通常的通信系统是单发单收&#xff0c;也就是SISO&#xff1a;Single-Input Single-…

【Bp2Lua】蓝图定义 Struct 和 Enum

【Bp2Lua】蓝图定义 Struct 和 Enum 背景 Enum Struct 结论 enum 可以保持不动&#xff0c;使用枚举值注释&#xff1b;如果C特别需要访问 enum&#xff0c;可以 C 化struct 必须 C 化 坑 首先&#xff0c;从字段访问都有字段名的坑&#xff0c;名字可以有空格&#xff0c…

maven-3-java调用python程序

【Java】使用Java调用Python的四种方法 fastjson的使用——JSON字符串、JSON对象、Java对象的互转 使用idea给Java程序打jar包&#xff08;超简单 超详细&#xff09; 1 环境准备 (1)新建Maven类型的项目&#xff0c;D:\processPython。 右键src/main/java&#xff0c;创建ja…

基于深度学习的文本分类6大算法-原理、结构、论文、源码打包分享

导读&#xff1a;文本分类是NLP领域一项基础工作&#xff0c;在工业界拥有大量且丰富的应用场景。传统的文本分类需要依赖很多词法、句法相关的human-extracted feature&#xff0c;自2012年深度学习技术快速发展之后&#xff0c;尤其是循环神经网络RNN、卷积神经网络CNN在NLP领…

【Leetcode面试常见题目题解】8. 合并两个有序链表

前言 本文是LC第21题&#xff1a;合并两个有序链表 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 提示&#xff1a; 两个链表的节点数目范围是 [0, 50] -100 < Node.val < 100 l1 和 l2 均按 非递减顺…

产品设计-基础控件-信息反馈控件

产品设计-基础控件-信息反馈控件1.1 吐司提示1.2 对话框1.3 气泡卡片1.4 动作面板和弹出层1.4.1 动作面板1.4.2 弹出层1.5 进度条和加载状态1.5.1进度条1.5.2 加载状态1.1 吐司提示 用户输入信息后&#xff0c;一个好的产品设计会给予用户明确的信息反馈&#xff0c;例如&…

五、pyhon-地图可视化篇(黑马程序猿-python学习记录)

黑马程序猿的python学习视频&#xff1a;https://www.bilibili.com/video/BV1qW4y1a7fU/ 目录 1. 基础地图 2. 设置分段 1. 基础地图 from pyecharts.charts import Map # 准备地图对象 map Map() # 准备数据 data[ ("北京",99), ("上海",199), ("…

【2023.01.23】定时执行专家 V6.6 兔年春节版 - 更新日志

目录 ◆ 最新版下载链接 ◆ 软件更新日志 – TimingExecutor Full Change Log ▼ 2023-01-23 V6.6 ▼ 2023-01-20 V6.5 ▼ 2022-12-25 V6.4 ▼ 2022-11-15 V6.3 ▼ 2022-10-01 V6.2 ▼ 2022-07-30 V6.1&#xff08;Build 769.30072022&#xff09; ▼ 2022-0…

[前端笔记——CSS] 10.层叠与继承+选择器

[前端笔记——CSS] 10.层叠与继承选择器1.层叠与继承1.1 冲突规则1.2 继承1.3 层叠1.4 CSS位置的影响2.选择器2.1 选择器是什么&#xff1f;2.2 选择器列表2.3 选择器的种类类型、类和 ID 选择器标签属性选择器伪类与伪元素运算符选择器参考表1.层叠与继承 1.1 冲突规则 CSS …