admin管理员组文章数量:1624327
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> > class priority_queue;
priority_queue的声明,可以看到底层默认是用vector实现的,并且第三个参数比较器默认是less
less的定义:
template<class T>
struct less:public binary_function<T,T,bool>{
bool operator()(const T& x,const T& y) const {return x<y;}
}
注意这里有个注意点,less的重载函数调用运算符的参数是const T&,其实这很正常,但是因为x是const,所以假如我们在T这个类的成员函数里实现重载< 运算符的时候,就要把它定义成 const 成员函数,不然程序error,因为常量对象无法调用非const成员函数——因为this指针默认是指向非常量对象的常量指针 T * const this (也就是非const 成员函数的this参数类型), 而一个底层const不能初始化一个普通的对象, const成员函数的this参数类型是 const T * const this。
在这里,我还学到了当成员函数不改变数据成员的时候,一定要切记定义成const成员函数,虽然之前就学过,但好像一直没当回事。在定义函数参数的时候,好多时候都是写成const T&,所以假如不是const成员函数,就没法被调用。
tips2:
默认是less,也就是用<确定优先级,并且是越大的优先级越大,所以默认是大顶堆
(记住跟谁都是false 的优先度最高)
//小顶堆
priority_queue<int,vector<int>,greater<int> > small_heap;
//大顶堆
priority_queue<int> big_heap;
tips3:
假如要定义自己的排序方法,我们要传给第三个模板参数是类,这里跟泛型算法不同,我之前想传lambda表达式,gg,因为lambda表达式实际上是一个未命名对象,而不是类,要想定义自己的排序方法有:
1) 类重载< 或者>运算符 (假如重载的是< 就用默认的less,假如重载的是>就用greater<T>),重载运算符可以是成员函数,但一定要是const成员函数,也可以是类T的(友元)全局函数,但是参数同样要是const T& 或者 传值 T 也ojbk
2)写一个函数类(重载了调用运算符的)
3)重头戏:
priority_queue() : c() {}
explicit priority_queue(const Compare& x) : c(), comp(x) {}
priority_queue的构造函数有这样两种,所以除了上面两种方法,我们还能用函数指针或者lambda的方式来实现定义自己的排序方法,但是要注意< > 这里的第三个参数依然要是类,而不能是一个对象,所以要么使用decltype (假如是函数指针的话,一定要 decltype(fun)*,最后的 * 别忘了加) 或者显式的用 function<返回类型 ( 参数 ) >
priority_queue<student, vector<student>, decltype(cmpfunc) *> que1(cmpfunc); // 注意一定要加上 *
priority_queue<student, vector<student>, function<bool(const student&, const student&)>> que1([](const student & a, const student & b) {return a.age < b.age; });
这里的组合方法就有很多了。
全部代码:
class student {
public:
int age;
string name;
/**重载小于操作符,
*可以成员,但一定要是const成员,也可以是非成员函数,但参数一定要是 const student& 或者 传值才可以
*/
bool operator<(const student & b) const { //必须要用const
return this->age < b.age;
}
friend bool operator<(const student& a, const student & b) {
return a.age < b.age;
}
student(int _age, string _name) :age(_age), name(_name) {}
};
/**可调用的函数操作符的对象*/
struct mycmp {
bool operator()(const student & a, const student & b) {
return a.age < b.age;
}
};
/**函数指针*/
bool cmpfunc(const student& a, const student& b) {
return a.age < b.age;
}
int main() {
/**默认使用student的oprator<来进行比较*/
priority_queue<student> que1;
/**使用重载函数操作符的类对象*/
priority_queue<student, vector<student>, mycmp> que2;
/*使用函数指针的形式*/
priority_queue<student, vector<student>, decltype(cmpfunc) *> que3(cmpfunc); // 注意一定要加上 *
/**使用lambda表达式*/
auto cmp = [](const student & a, const student & b) {return a.age < b.age; };
priority_queue<student, vector<student>, decltype(cmp)> que4(cmp);
/**
* 需要把lambda表达式作为优先队列参数进行初始化
* 并且指定priority_queue的模板实参,decltype(cmp),
* 可以认为是确定函数的类型
* bool (const student & a,const student & b)
**/
//使用lambda表达式方法2
priority_queue<student, vector<student>, function<bool(const student&, const student&)>> que5([](const student & a, const student & b) {return a.age < b.age; });
//使用函数指针方法2
//函数指针来初始化函数对象
priority_queue<student, vector<student>, function<bool(const student&, const student&)>> que6(cmpfunc);
system("pause");
}
本文标签: 运算符priorityqueue
版权声明:本文标题:priority_queue重载小于运算符的问题 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1728896900a1178528.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论