C++仿函数
admin
2024-02-21 06:07:50
0

仿函数

仿函数又称为函数对象,是一种能够行使函数功能的类,该类重载了operator()运算符,调用仿函数的时候实际上就是通过类对象调用重载后的operator操作符,重载operator()和重载普通的函数效果相同,当参数类型不同时会执行不同的代码逻辑。仿函数使用
比如自定义了一个仿函数A

#include 
#include 
using namespace std;
class A{
public:
int operator() (int a, int b){
return a+b;
}
double operator() (double a, double b){
return (a+b)*2;
}
};
int main(){
A a;
auto c1 = a(1, 2);
cout << typeid(c1).name() << " " << c1 << endl;
auto c2 = a(11.3, 2.4);
cout << typeid(c2).name() << " " << c2 << endl;
}

C++标准库中的仿函数存在在于functional.h中,平时用到的最多的是greater,less这两个,这两个函数常被用做排序函数的参数。在排序函数中greater和less这两个函数可以被等效的lambda表达式替换。但是在优先队列中,不能直接使用lambda表达式替换。

所以才会接触到仿函数这个概念。优先队列自定义比较规则,可以使用仿函数或者对被比较的类重载小于操作符。由于C++规定操作符重载必须至少有一个类类型的操作数,因此当优先队列中的元素不是自定义类的时候,则没法对其重载小于操作符,此时只能实用仿函数来实现自定义的比较规则。
以下是为优先队列定义仿函数的示例

#include 
#include 
#include 
using namespace std;
class comp{
public:
bool operator(const pair &a, const pair &b) {
return a.second < b.second;
}
};
int main(){
priority_queue, vector>, comp> q;
q.push({1,3});
q.push({2,4});
q.push({3,6});
auto p = q.top();
cout << p.first << " " << p.second << endl;
}

函数对象 vs 模板类型参数
很多人C++初学者会有这样的疑惑,在sort中可以使用lambda,而在优先队列的定义中不能使用,相反,在优先队列中可以使用仿函数,而在sort中则不能使用仿函数。
这个问题的根源在于没有分清楚仿函数(函数对象)和模板类型参数之间的关系。
sort函数的原型为

template 
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

可以看到 comp是一个函数对象,因为lambda对象也属于函数对象,所以可以作为排序的参数。C++中凡是能够调用()运算符的就都是函数对象,包括函数、函数指针、重载了()运算符的对象,以及lambda对象。
优先队列的构造函数原型为

template<
class T,
class Container = std::vector,
class Compare = std::less
> class priority_queue;

填入尖括号中的应该是类型的名字,即typename,当然不能使用lambda作为typename,但是我们使用decltype来获得lambda的类型,作为typename,然后在构造函数的参数中把lambda示例传进去,就能work。
示例如下

#include
#include
using namespace std;
int main(){
auto comp = [](const pair &a, const pair &b){
return a.second < b.second;
};
priority_queue, vector>, decltype(comp)> q(comp);
q.push({1,3}); q.push({2,4}); q.push({3,6});
auto p = q.top();
cout << p.first << " " << p.second << endl;
}

相关内容

热门资讯

华夏银行跌1.71% 领跌银行... 中国经济网北京1月30日讯 华夏银行(600015.SH)今日股价收报6.34元,跌幅1.71%。今...
帮主郑重:1月A股深V收官!2... 1月最后一天A股又玩深V,你是抄底抄在半山腰,还是吓得割在最低点?帮主郑重做财经20年,见过无数次市...
黄金跌破5000美元关口,白银... 30日下午,现货黄金、白银再次加速下跌。 截至发稿,现货黄金跌超7%,跌破5000美元/盎司,日内重...
Meta首席财务官:仍在打造头... IT之家 1 月 30 日消息,在 Meta 本周举行的 2025 年第四季度财报电话会议中,有德意...
新股消息 | 新济医药、翼菲科... 智通财经APP获悉,1月30日,中国证监会发布《境内企业境外发行证券和上市备案情况表(首次公开发行及...
国投白银LOF30日停牌 溢价... 来源:滚动播报 (来源:千龙网) 为保护投资者利益,国投白银LOF发布公告,将于今天(30日)开市起...
NexBridge清桥国际清洁... 上证报中国证券网讯(记者 闫婧)1月29日,由国际化的清洁能源生态领军机构New Energy Ne...
金价高位震荡 大量市民涌入银行... 最近一段时间,黄金价格屡创新高。今天(1月30日),国际金价又迎来“过山车”式震荡。尽管金价“上蹿下...
人民币兑美元实现连续第十个单周... 观点网讯:1月30日,在岸人民币兑美元本周以来累计上涨约0.2%,即将实现连续第十个单周上涨,这将是...
藏格矿业大宗交易折价成交42.... 藏格矿业01月30日大宗交易平台共发生1笔成交,合计成交量42.00万股,成交金额3570.42万元...
美股异动丨游戏驿站盘前涨超1%... 游戏驿站(GME.US)盘前涨1.05%,报23.05美元。消息面上,游戏驿站CEO表示,他希望将这...
「黑红出圈」5个月后,Maca... 文 | 镜相工作室,作者丨马舒叶,编辑丨卢枕 进入2026年,大厂似乎正主导新一轮的AI叙事。无论...
承压前行 稳中有进——2025... 近日,航拍镜头下的宁德门下锂电智能制造配套产业园。郑霄 摄 1月29日,2025年宁德经济运行数据“...
央行进行 4,775 亿元 7... 来源:滚动播报 央行进行 4,775 亿元 7 天期逆回购操作 操作利率 1.4%。
电费刺客退散!全球首台“超碳一... 起猛了?二氧化碳居然不是“温室背锅侠”,而是发电界的“新晋牛马”? 夏天开空调怕遇到“电费刺客”,工...
天天喊房价完了的人,醒醒!暴跌... 最近有消息称,监管部门不再要求房企每月上报“三条红线”指标,这也意味着2020年以来卡在开发商脖子上...
践行金融初心│宁波银行绍兴分行... 2025年,宁波银行绍兴分行紧紧围绕国家金融“五篇大文章”战略部署,始终牢记金融服务实体经济的初心使...
本周A股市场涨跌榜:沪指站稳4... 本周(1月26日至1月30日),A股三大指数全部收跌。截至周五收盘,上证指数累计下跌0.44%,深证...
太仆寺旗市场监督管理局计量和标... 新春佳节将至,为规范节日市场计量秩序,切实保障消费者合法权益,营造公平诚信的消费环境,太仆寺旗市场监...
西部提速、广东放缓,经济学者解... 来源:滚动播报 (来源:财闻) “过去我们谈区域经济,总是盯着‘北上广’,但现在看数据,格局明显多极...