sort(函数模板)和priority_queue(类模板)的比较器重载

embedded/2025/1/20 3:53:00/

一、sort的比较器重载

sort是一个函数模板,定义如下

它的比较器重载的两种方法:

1. 传函数指针

#include <iostream>
#include <algorithm>using namespace std;class Node
{
public:int value;Node() { value = 0; };explicit Node(int value){this->value = value;}
};bool cmp(const Node& n1, const Node& n2)
{return n1.value > n2.value;
}int main()
{Node* a = new Node[5];a[0].value = 2;a[1].value = 5;a[2].value = 2;a[3].value = 9;a[4].value = 0;sort(a, a + 5, cmp);for (int i = 0; i < 5; i++) {cout << a[i].value << " ";}return 0;
}

注意:在类中时,需要注意加上static,因为非静态函数不加static指针的时候,会隐藏地传一个this指针,导致参数表不符

2. 使用仿函数

#include <iostream>
#include <algorithm>using namespace std;class Node
{
public:int value;Node() { value = 0; };explicit Node(int value){this->value = value;}
};class CMP
{
public:bool operator()(const Node& n1, const Node& n2){return n1.value > n2.value;}
};int main()
{Node* a = new Node[5];a[0].value = 2;a[1].value = 5;a[2].value = 2;a[3].value = 9;a[4].value = 0;sort(a, a + 5, CMP());for (int i = 0; i < 5; i++) {cout << a[i].value << " ";}return 0;
}

二、priority_queue的比较器重载

priority_queue是一个类模板,定义如下

它的构造函数如下:

需要注意的是,priority_queue是一个类模板,而sort是一个函数模板,因此在重载的时候有些区别

它的比较器重载的两种方法:

1. 传函数指针

#include <iostream>
#include <queue>using namespace std;class Node
{
public:int value;Node() { value = 0; };explicit Node(int value){this->value = value;}
};bool cmp(const Node& n1, const Node& n2)
{return n1.value > n2.value;
}int main()
{Node* a = new Node[5];a[0].value = 2;a[1].value = 5;a[2].value = 2;a[3].value = 9;a[4].value = 0;priority_queue<Node, vector<Node>, decltype(&cmp)> pq(cmp);pq.push(a[0]);pq.push(a[1]);pq.push(a[2]);pq.push(a[3]);pq.push(a[4]);while (!pq.empty()){cout << pq.top().value << " ";pq.pop();}return 0;
}

注意:在类中时,也需要注意加上static

2. 使用仿函数

#include <iostream>
#include <queue>using namespace std;class Node
{
public:int value;Node() { value = 0; };explicit Node(int value){this->value = value;}
};class CMP
{
public:bool operator()(const Node& n1, const Node& n2){return n1.value > n2.value;}
};int main()
{Node* a = new Node[5];a[0].value = 2;a[1].value = 5;a[2].value = 2;a[3].value = 9;a[4].value = 0;//CMP cmp;//priority_queue<Node, vector<Node>, CMP> pq(cmp); // 也可以传,但完全没必要priority_queue<Node, vector<Node>, CMP> pq;pq.push(a[0]);pq.push(a[1]);pq.push(a[2]);pq.push(a[3]);pq.push(a[4]);while (!pq.empty()){cout << pq.top().value << " ";pq.pop();}return 0;
}

三、常见疑问

  • priority_queue比较器重载传函数指针时是priority_queue<Node, vector<Node>, decltype(&cmp)> pq(cmp);,那么decltype(&cmp)可不可以换成decltype(cmp)呢?

答:不可以,虽然函数名很多时候和函数名取地址使用起来一样,但这里确实是不一样的,decltype(&cmp)是bool (*)(const Node& n1, const Node& n2),而decltype(&cmp)却是bool (const Node& n1, const Node& n2),不仅仅是decltype,当使用typeid查看类型时它们也不一样,它们的typeid如下图所示。可能原因是函数名是表明这种函数类型的类型,只是在大多数场景下我们使用它时它隐式类型转换变成了函数指针。

  • priority_queue比较器重载使用仿函数时可以不用给构造函数传参,而为什么使用用函数指针时一定要给构造函数传递函数指针呢,它不是也像使用仿函数时一样传递了类型吗?

答:priority_queue的构造函数中对应比较器的参数是const Compare& comp = Compare(),而它有缺省参数,并且是一个匿名对象,其中Compare就是给模板传递的类型,使用仿函数本质是定义了一个类,并使用运算符重载重载了(),当使用仿函数时向模板传递的是一个类类型,而类类型是对应唯一的一个类的,用类类型定义匿名对象可以用来调用该类的函数成员,所以当使用仿函数时构造函数可以直接用缺省参数给比较器初始化,而传递函数指针时给模板传递的是函数指针类型,而函数指针类型的匿名对象跟类的匿名对象完全不一样,一个函数指针类型可以对应无数个拥有相同返回值和相同参数的函数的指针,所以它的匿名对象规定为是0,而值为0的函数指针并不能用来调用函数,所以必须传递需要调用的函数的函数指针。


http://www.ppmy.cn/embedded/155377.html

相关文章

ES6的高阶语法特性

一、模板字符串的高级用法 1.1.模板字符串的嵌套 模板字符串的嵌套允许在一个模板字符串内部再嵌入一个或多个模板字符串。这种嵌套结构在处理复杂数据结构或生成具有层级关系的文本时非常有用。 1. 嵌套示例 假设我们有一个包含多个对象的数组&#xff0c;每个对象都有名称、…

linux 安装Redis

下载Redis http://download.redis.io/releases将下载的安装包上传到服务器解压安装包&#xff1a;程序一般放在opt下 &#xff0c;我们可以使用命令将文件移动到对应目录 mv redis-7.0.5.tar.gz /opt使用命令对Redis文件进行解压&#xff1a; tar zxvf redis-7.0.5.tar.gz进…

模拟器多开窗口单IP与代理IP关系

模拟器多开窗口同IP背后出现的问题 在游戏世界中&#xff0c;模拟器多开窗口是玩家们提升体验的常见做法。通过在同一设备上开启多个模拟器窗口&#xff0c;玩家可以同时运营多个游戏账号&#xff0c;增加游戏的趣味性和效率。 一旦检测到一个IP地址下登录了过多的账号&#x…

结合帧级边界检测和深度伪造检测,定位部分伪造音频攻击中的篡改区域

Integrating frame-level boundary detection and deepfake detection for locating manipulated regions in partially spoofed audio forgery 摘要&#xff1a; 部分伪造音频是一种深度伪造的变体&#xff0c;它通过引入伪造或外部来源的善意音频片段来操纵音频语句&#xf…

文件上传生成pdf

前端后端 import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile;import java.io.File; import java.io.IOException;Re…

基于微信小程序的中国各地美食推荐平台的设计与实现springboot+论文源码调试讲解

第4章 系统设计 4.1 系统设计的原则 在系统设计过程中&#xff0c;也需要遵循相应的设计原则&#xff0c;这些设计原则可以帮助设计者在短时间内设计出符合设计规范的设计方案。设计原则主要有可靠性&#xff0c;安全性&#xff0c;可定制化&#xff0c;可扩展性&#xff0c;可…

什么是 OpenResty

1、OpenResty简介 1.1 了解OpenResty OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台&#xff0c;其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。 简单地说OpenRes…

【计算机体系结构、微架构性能分析】core 与 uncore 分别是哪一些部分?区分 core 和 uncore

在计算机体系结构中&#xff0c;Core 和 Uncore 是描述处理器内部架构的两个重要概念&#xff0c;尤其在多核处理器中更为常见。 1. Core&#xff08;核心&#xff09; Core 指的是处理器中的计算核心&#xff0c;是执行指令和处理数据的基本单元。每个核心都包含独立的执行单…