C++中的仿函数效果类似于C语言中使用函数指针和回调函数
具体参考:C语言quick sort的实现(quicksort函数的最后一个参数是函数指针
)
仿函数是模板函数,也可以叫做函数对象
,本质就是其实现就是类中实现一个operator()
,其速度比一般函数要慢
在priority_queue里用的仿函数less来做模板的最后一个缺省参数
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> >
class priority_queue;
它在这里的作用就是修改向上/向下调整算法的父子节点的比较条件 (大于(小堆
),小于(大堆
))
下面是具体实现
:
template <class T>
struct Less
{
bool operator()(const T& x,const T& y)
{
return x < y;
}
};
template <class T>
struct Greater
{
bool operator()(const T& x, const T& y)
{
return x > y;
}
};
所以:
-
我们在模拟实现的时候把priority_queue的模板改为:
template <class T, class Container = std::vector<T>, class Compare = std::less<typename Container::value_type> >
-
多定义一个成员变量Compare comp
用于算中的比较
-
在堆向上/向下调整算法中将所有节点之间的比较改为comp(c[parent], c[child])
或comp(c[child], c[child+1])
例子
:(通过仿函数控制比较方式)
有一个Date类 (已经重载了输出<<和比较<
)
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{}
bool operator<(const Date& d)const
{
return (_year < d._year) ||
(_year == d._year && _month < d._month) ||
(_year == d._year && _month == d._month && _day < d._day);
}
friend ostream& operator<<(ostream& _cout, const Date& d);
private:
int _year;
int _month;
int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
_cout << d._year << "-" << d._month << "-" << d._day<<endl;
return _cout;
}
而实例化priority_queue的时候将Date*做为类型传入的(默认使用的是fonctional.h里的less仿函数
)
priority_queue<Date*, vector<Date*>> pq;
pq.push(new Date(2023, 11, 24));
pq.push(new Date(2021, 10, 24));
pq.push(new Date(2021, 12, 24));
pq.push(new Date(2022, 1, 24));
cout<< (*pq.top()) << endl;
输出的是2022-1-24而不是2023-11-24
,因为优先队列里存的是地址
,less函数对象比较的也是地址
,优先级最高的是地址最大的即最后new的对象Date(2022, 1, 24)
所以这里需要我们自己实现
一个针对这种情况的PDataLess函数对象:
class PDateLess
{
public:
bool operator()(const Date* p1, const Date* p2)
{
return *p1 < *p2;
}
};
同时在Date类里添加PDateLess友元:friend class PDateLess;
实例化priority_queue时传入的参数应该为:priority_queue<Date*, vector<Date*>, PDateLess> pq;