从优先队列中重载小于号谈起
看一个问题
看下面这段代码
// cpp
struct node {
int a, b;
bool operator< (const node& x) {
return a > x.a;
}
};
int main()
{
priority_queue<node> pq;
pq.push(node{1, 2});
return 0;
}
代码意图声明一个结构体并重载小于号,以使用优先队列维护
但是过不了编译,部分报错信息如下
追踪
看一下 /usr/include/c++/6/bits/stl_function.h:386:20
指向的代码
// cpp
template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool>
{
_GLIBCXX14_CONSTEXPR
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
可以看到 less()
这个函数对象 (function object)
重载了 ()
运算符,接收两个 const
类型的参数
而在 cpp
里面,只有 const
成员函数才能够被 const
对象调用
这是编译器为了保证成员函数不会修改 const
对象的成员变量,所做出的强制要求
解决
解决方法很简单,把重载运算符的函数声明为 const
即可
// cpp
struct node {
int a, b;
bool operator< (const node& x) const {
return a > x.a;
}
};
int main()
{
priority_queue<node> pq;
pq.push(node{1, 2});
return 0;
}
为优先队列重载小于号的四种办法
给定结构体
// cpp
struct node {
int a, b;
};
int main()
{
priority_queue<node> pq;
pq.push(node{1, 2});
return 0;
}
为它重载小于号,以支持优先队列来维护它
在类内声明成员函数
声明为 const
的成员函数,输入参数也得是 const
// cpp
struct node {
int a, b;
bool operator< (const node& x) const
{
return a > x.a;
}
};
int main()
{
priority_queue<node> pq;
pq.push(node{1, 2});
pq.push(node{2, 3});
cout << pq.top() << endl; // 输出: 1 2
return 0;
}
考虑一个简单的声明
const node A{1, 2};
const node B{3, 4};
那么有如下等价的语句
(A < B) <=> A.operator< (B)
因此一切变得可以理解起来了
- 由于是
const
对象的比较,所以声明为const member function
- 由于传入的参数也是
const
对象,所以成员函数的参数也要设置为const
,以扩大接受对象的范围
在类内声明为友元函数
// cpp
struct node {
int a, b;
friend bool operator< (const node& x, const node& y)
{
return x.a > y.a;
}
};
int main()
{
priority_queue<node> pq;
pq.push(node{1, 2});
pq.push(node{2, 3});
cout << pq.top() << endl; // 输出: 1 2
return 0;
}
友元函数虽然定义在类内,但是不是类的成员函数,只是具有类成员变量的访问权
在类外重载小于号
// cpp
struct node {
int a, b;
};
bool operator< (const node& x, const node& y)
{
return x.a > y.a;
}
int main()
{
priority_queue<node> pq;
pq.push(node{1, 2});
pq.push(node{2, 3});
cout << pq.top() << endl; // 输出: 1 2
return 0;
}
声明新的函数对象
// cpp
struct node {
int a, b;
friend ostream& operator<< (ostream& out, const node& x) {
out << x.a << ' ' << x.b;
}
};
struct cmp {
bool operator() (const node& x, const node& y) {
return x.a > y.a;
}
};
int main()
{
priority_queue<node, vector<node>, cmp> pq;
pq.push(node{1, 2});
pq.push(node{2, 3});
cout << pq.top() << endl; // 输出: 1 2
return 0;
}