04.08_111期_C++_reverseiterator实现和理解

priority_queue这个类中的top()获得的是数据较大的优先级高,

priority_queue其底层实现就是一个大根堆

priority_queue<int> pq;

传入以下的模板参数,其中 greater<int> 保证了 生成的 pq 对象是小根堆

greater<int>为仿函数

vector<int> v = { 3, 1, 7, 4, 6, 3 };

//升序

sort(v.begin(), v.end());

for (auto e : v)

{

cout << e << " ";

}

cout << endl;

降序: 要借助仿函数greater<int>,可以使用几种方法

第一种:使用具体的实例化对象

greater<int> gt;

sort(v.begin(), v.end(), gt);

第二种 匿名对象

这里之所以使用了greater<int>()创建一个属于 greater<int>类 的匿名对象

是因为sort是一个函数,其参数的类型都是函数模板给出的,所以传入参数时要给确切的实例化对象

仿函数就是一个普通的类

这个类创建出来的实例可以像函数名一样,对()内进行传实参后使用

这个类对()这个运算符进行重载,使得下面两种用法相等

  1. 实例化对象.operator()(参数1, 参数2, ...)

  2. 实例化对象(参数1, 参数2, ...)

priority_queue这个类中的top()获得的是数据较大的优先级高,

priority_queue其底层实现就是一个大根堆

priority_queue<int> pq;

传入以下的模板参数,其中 greater<int> 保证了 生成的 pq 对象是小根堆

greater<int>为仿函数

下面三种push元素的方式:

方式一:先创建一个Date的实例,再用这个实例进行push

方式二:生成一个匿名对象之后,将这个匿名对象进行push

方式三:隐式类型转换,生成临时对象之后,将这个匿名对象进行push

为什么以下函数给第三个位置直接传了一个 名叫GreaterPDate的形参

  1. 如果直接传入bit::greater<Date*>,

是无法调到bool Date::operator>(const Date& d) const 这个函数的

因为Compare com; 这句话实际上是执行了 greater<Date*> com;这句话

com(_con[parent], _con[child]); 这句话实际上就执行了 greater类中的函数 operator()

而且传入参数时是执行

bool operator()(const Date* x, const Date* y)

{

return x > y;

}

以上函数在执行到 return x > y; 这句话时

那么就要调用 Date类中的 operator> 这个函数,对应执行的是

可此时的函数的形参类型是 const Date& 类型,不是const (Date*)& d 类型

  1. 在main函数上方直接定义一个函数,如果函数声明是

σ:bool operator<(const Date* d1, const Date* d2); 同样不能使用

bit::priority_queue<Date*, vector<Date*>, bit::greater<Date*>> pqptr;这句话

因为无论什么类型,只要加上了 * 号,就变成了指针类型的变量,

就一定是一个内置类型的变量,那么σ处的声明就完全没有用到自定义类型

此时的运算符重载就不符合语法规定,

语法规定要对 >, <, ==, != 这一类的逻辑运算符进行重载时,

声明的参数列表中至少要有一个自定义类型的参数

  1. 如果非要在优先级队列中传入Date*作为模板参数,只能使用仿函数的方法

在优先级队列的逻辑中不像 2. 那样去重新重载专门属于Date* 的比较逻辑

而是通过com这个实例对应的类是一个如下的仿函数

其中 return *p1 > *p2; 这句话中的 > 还是

调用了Date这个类中的bool Date::operator>(const Date& d) const这个函数

class GreaterPDate

{

public:

bool operator()(const Date * p1, const Date * p2)

{

return *p1 > *p2;

}

};

而在执行到com(_con[parent], _con[child])这个代码

可以通过GreaterPDate这个类中对 () 进行重载的操作符

即通过这个运算符调用bool operator()(const Date * p1, const Date * p2)这个函数

通过上面的分析可知,仿函数可以在函数要执行不同的逻辑时调用不同的函数

priority_queue是容器适配器,只是与stack, queue 这另外两种适配器不同的是,

priority_queue还需要仿函数参数控制大根堆和小根堆

bit::queue<int> st;

st.push(1);

st.push(2);

st.push(3);

st.push(4);

st.push(5);

printf("size: %d\n", st.size());

for (size_t i = 0; !st.empty(); i++)

{

if (!st.empty())

{

cout << st.front() << " ";

st.pop();

}

}

cout << endl;

Less<int> ls;

下面这几句话是等价的

cout << ls(1, 2) << endl;

cout << ls.operator()(1, 2) << endl;

cout << Less<int>()(1, 2) << endl;

cout << Less<int>().operator()(1, 2) << endl;

这个文件σ设计一个对应任意容器的反向迭代器

也就是迭代器适配器

既然是适配器,那么只要模板参数确定,这个适配器类就要有对应的属性

这样就不用在每个容器类的内部专门都定义一个反向迭代器的行为了

每个容器要使用 反向迭代器 都是调用σ中的迭代器类,

然后调用文件σ中对应的反向迭代器

而这个 反向迭代器类 中的所有运算符重载成员函数

都是调用 正向迭代器 的类中的已经重载过的运算符

ReverseIterator这个类在实现时要达到的效果是:

只要有一个具体的容器类的正向迭代器,就能获得属于这个容器类的 反向迭代器

比如给 list<T>::iterator,经过这个类就得到 list<T>::ReverseIterator

在STL中实现的形式就是:

typedef __list_iterator<T, T&, T*> iterator;

typedef __list_iterator<T, const T&, const T*> const_iterator;

typedef reverse_iterator<iterator> reverse_iterator;

typedef reverse_iterator<const_iterator> const_reverse_iterator;

相关推荐
fqbqrr2 小时前
2601C++,cmake与导入
c++
fqbqrr3 小时前
2601C++,编写自己模块
c++
王老师青少年编程6 小时前
2025年12月GESP真题及题解(C++七级): 城市规划
c++·gesp·csp·信奥赛·七级·csp-s·提高组
寻星探路7 小时前
【算法专题】滑动窗口:从“无重复字符”到“字母异位词”的深度剖析
java·开发语言·c++·人工智能·python·算法·ai
我叫袁小陌8 小时前
C++多线程全面详解
开发语言·c++
m0_748250039 小时前
C++ 官方文档与标准
开发语言·c++
matlabgoodboy9 小时前
程序代做python代编程matlab定制代码编写C++代写plc设计java帮做
c++·python·matlab
DYS_房东的猫9 小时前
《 C++ 零基础入门教程》第6章:模板与 STL 算法 —— 写一次,用万次
开发语言·c++·算法
点云SLAM9 小时前
C++ 静态初始化顺序问题(SIOF)和SLAM / ROS 工程实战问题
开发语言·c++·slam·静态初始化顺序问题·工程实战技术·c++static 关键字
pen-ai10 小时前
打通 Python 与 C++ 的参数传递机制
开发语言·c++·python