C++候捷stl-视频笔记3

2024-06-05 07:44
文章标签 c++ 视频 笔记 stl 候捷

本文主要是介绍C++候捷stl-视频笔记3,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法的形式

在这里插入图片描述
Cmp通常是个比大小的准则,是Functor。
算法所需的信息通常指迭代器如何移动

迭代器的分类

在这里插入图片描述
array,vector,deque它们是连续的,它们的迭代器是Random Access Iterator/随机访问迭代器
list的迭代器是Bidirectional Iterator/双向迭代器
forward_list的迭代器是Forward Iterator/前向迭代器
基于红黑树的set/multiset, map/multimap它们都是Bidirectional Iterator
基于hashtable的unordered_set, unordered_multiset, unordered_map, unordered_multimap的迭代器是双向的(Bidirectional Iterator)还是单向的(Forward Iterator),要看bucket对应的链表具体是双向链表还是单向链表。具体到STL应该是forward_iterator
在这里插入图片描述
根据分类自己打印各容器的迭代器类型字符串
在这里插入图片描述
利用c++本身typeid打印出迭代器类型
在这里插入图片描述
父类没有数据和函数,只有typedef。目的是为了让子类拥有这些别名,方便写代码
在这里插入图片描述

迭代器分类对算法的影响

在这里插入图片描述
distance:知道两个指针的距离,相当于两个指针相减。如果无法相减,只能循环

typename 的使用是为了指定 iterator_traits<_InputIterator>::difference_type 表示一个类型。iterator_traits<_InputIterator>::difference_type 是迭代器 _InputIterator 的差值类型(表示两个迭代器之间的距离),而 typename 在这里是为了明确告诉编译器这是一个类型而不是其他类型的标 识符
在这里插入图片描述
advance函数会根据iterator_category(__i)的类型选择调用不同的__advance的实现

容器迭代器的分类是基于对象(存在继承关系),而不是基于enum(枚举类型)

迭代器虽然有5种,但根据继承关系(子类is a 父类),只要实现了父类,不需要5种都实现
在这里插入图片描述
copy会不断地做检查,检查是否为某种迭代器,决定copy是否要做某些操作来加速
traits区分赋值拷贝重不重要,如复数类,没有指针不重要
在这里插入图片描述
destroy和前面类似,不断细分类型。traits区分析构函数重不重要
在这里插入图片描述
在这里插入图片描述
unique_copy例子
在这里插入图片描述
算法是模板函数,可以接收任意类型的参数,语法没法指定传入的参数类型
因此在定义模板参数名称的时候,会命名(暗示)它想要接收的类型,比如下图,distance函数想要接收的是input iterator,而sort想要接收的是random access iterator,rotate函数想要接收forward iterator等等

算法源码剖析

在这里插入图片描述
C++标准库提供的algorithm需要符合如下接口

template<typename Iterator>
std::Algorithm(Iterator itr1, Iterator itr2, ...)
{...
}

在这里插入图片描述
一般函数都有两个版本,第二个版本一般是允许增加一种原则或者操作,从而应用的更广泛

myobj是个函数对象,是myclass类,重载了()
在这里插入图片描述
for_each让范围里的所有元素都依次做同一件事情
在这里插入图片描述
replace:范围内的所有等于 old_value 的,都被 new_value 取代
replace_if:范围内所有满足 pred() 为 true 的元素都被 new_value 取代
replace_copy:范围内的元素全部 copy 到新地方,其中所有等于 old_value 的,都被替代为 new_value
在这里插入图片描述
count:在范围中计数值等于 value 的个数
count_if:在范围中计数满足条件 pred() 的个数
所有关联式容器自带成员函数 count()
在这里插入图片描述
find:在范围内找到值等于 value 的元素
find_if:在范围内找到满足 pred() 的元素
所有关联式容器自带成员函数 find()
在这里插入图片描述
所有关联式容器((本身就排好序了)没有成员函数 sort(),array,vector,deque也没有
list、forward_list无法跳跃,因此只能使用自带sort
在这里插入图片描述
逆向迭代器,rbegin()使用end(),然后套用一个reverse_iterator适配器
在这里插入图片描述
二分查找是否存在目标元素(并不给予位置),使用前必须先排序;主要使用 lower_bound() 来找到能放入 val 的最低位置,再判断该元素是否存在

仿函数和函数对象

仿函数只为算法服务,提供一些特殊准则
在这里插入图片描述
在这里插入图片描述
GC++独有的仿函数
在这里插入图片描述
sort仿函数
在这里插入图片描述
STL中的每个仿函数都继承了binary_function<T, T, bool>,表示有两个操作数的操作,共3个模版参数,对应的还有unary_function,表示有1个操作数的操作(如否定)

如果希望自己写的仿函数可以修改,适配,融入stl,就需要继承上述两个结构之一因为adpat可能向functors提问上述三个别名

仿函数就是一个class里头的重载小括号,这样的class创建的对象就是函数对象/仿函数,因为做出来的是一个对象但像一个函数

存在多种Adapter

迭代器适配器(Iterator Adapters):用于在不同迭代器之间进行转换或提供额外功能的适配器。例如,std::back_inserter、std::front_inserter、std::inserter 等。
函数适配器(Function Adapters):用于在函数对象之间进行转换或提供额外功能的适配器。例如,std::bind、std::function 等。
容器适配器(Container Adapters):提供不同接口的容器,例如,std::stack、std::queue、std::priority_queue 等

改造例子:stack 中将 deque 的 push_back 改名为 push

函数适配器

binder2nd

在这里插入图片描述
binder2nd是函数适配器之一,用于将一个二元操作函数(_Operation)和一个固定的值(__y)绑定在一起 —— 绑定第二参数

binder2nd类继承自unary_function,表示其为一元函数对象,其operator()用于执行绑定的操作
在这里插入图片描述

not1

在这里插入图片描述

bind

在这里插入图片描述
占位符 placeholders:
using namespace std::placeholders;
提供了 _1,_2,_3,·······
上面的的 _1 指的是被绑函数中的第一个参数

// functions
double my_divide(double x, double y)
{return x/y;
}// function objects 测试与functions同理
// divides<double> my_divide;struct MyPair
{// data membersdouble a, b;// member functionsdouble multiply(){return a*b;}
};
auto fn_five = bind(my_divide, 10, 2);
cout << fn_five() << endl; // 5.0auto fn_half = bind(my_divide, _1, 2);
cout << fn_half(10) << endl; // 5.0auto fn_invert = bind(my_divide, _2, _1);
cout << fn_invert(10, 2) << endl; // 0.2//将 my_divide 的返回类型变为 int,即 int(x/y)
auto fn_rounding = bind<int>(my_divide, _1, _2); 
cout << fn_rounding(10, 3) << endl; // 3MyPair ten_two {10, 2};  //定义一个实例ten_two
//绑定 member functions,由于成员函数有 this,所以 _1 就相当于 this,即 x.multiply()
auto bound_memfn = bind(&MyPair::multiply, _1);
cout << bound_memfn(ten_two) << endl; // 20//把实例 ten_two 绑定到 a,即 ten_two.a
auto bound_memdata = bind(&MyPair::a, ten_two);
cout << bound_memdata() << endl; // 10auto bound_member_data2 = bind(&MyPair::b, _1);
cout << bound_member_data2(ten_two) << endl;

迭代器适配器

reverse_iterator

在这里插入图片描述
对逆向迭代器取值,就是取其所指正向迭代器的前一个位置

inserter

在这里插入图片描述
对于 copy(InputIterator first, InputIterator last, OutputIterator result),其会不管 OutputIterator 后是否有充裕空间,对 result 开始依次赋值
因此对=操作符重载,将iterator的赋值操作改变为insert操作,如上图下面部分

ostream_iterator

ostream适配器,因为是为了改造basic_ostream
用于将数据输出到输出流(ostream)。它是一个模板类,通常用于将容器中的元素输出到输出流,或者将其他可输出的数据类型输出到流中
在这里插入图片描述
将 copy 变为一个输出工具,分隔符是 ,
其核心依然是操作符重载,这样就相当于 cout<<*first; cout<<“,”;

istream_iterator

用于从输入流(istream)中读取数据。它是一个模板类,通常用于从输入流中读取数据到容器中,或者直接读取输入流中的数据
在这里插入图片描述在创建 iit 的时候就已经把所有的键盘输入读进去了,之后就是一个一个取出来赋值给 value 的操作
++iit; 语句用于使 istream_iterator 前进到输入流的下一个元素。
在这里插入图片描述
copy和istream iterator适配器,对操作符进行重载,实现和cin的同步

这篇关于C++候捷stl-视频笔记3的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1032477

相关文章

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

详解C++中类的大小决定因数

《详解C++中类的大小决定因数》类的大小受多个因素影响,主要包括成员变量、对齐方式、继承关系、虚函数表等,下面就来介绍一下,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 非静态数据成员示例:2. 数据对齐(Padding)示例:3. 虚函数(vtable 指针)示例:4. 继承普通继承虚继承5.

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque