1. 重载"<"运算符
第一种:写在struct或class的内部。下面是一个例子:
class Node {
public:
int x_, y_;
Node(int x, int y) :x_(x), y_(y) {}
//重载"<"运算符(写在类内部)
bool operator<(const Node& a)const { // 返回true,表示this的优先级小于a
// x大的排在前面;x相同时,y大的排在前面
if (x_ == a.x_) {
return y_ > a.y_;
}
return x_ > a.x_;
}
};
int main() {
// 待排序数组
vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
sort(vec.begin(), vec.end());// 重载"<"运算符
}
写在内部的就需要注意两个const。因为运算符<
的重载可以看作node_b.operator<(node_a)
,priority_queue
在对元素进行比较的时候,两个元素都是const类型的。因此,运算符<
的重载必须能满足两个const类型的元素进行比较。我们来看,第一个const,即const Node a表示的是node_a必须为const;第二个const,即函数声明之后的那个const,表示的是运算符<可以被const类型的node_b调用。有了这两个const,才能满足两个const类型的元素进行比较。
第二种:写在struct或class的外部。
class Node {
public:
int x_, y_;
Node(int x, int y) :x_(x), y_(y) {}
}
// 重载"<"运算符(写在类外部)
bool operator<(Node& a, Node& b) { // 返回true,表示this的优先级小于a
// x大的排在前面;x相同时,y大的排在前面
if (a._x == b._x) {
return a._y > b._y;
}
return a._x > b._x;
}
int main() {
// 待排序数组
vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
sort(vec.begin(), vec.end());// 排序
}
2. 重写函数对象(仿函数)
函数对象也叫做仿函数,《STL源码剖析》中是这么解释的:“函数对象是一种具有函数特质的对象”。函数对象是一个广泛的概念,所有具有函数行为的对象都可以称为函数对象。所谓的函数行为是指的是可以使用()调用并传递参数。广义上来讲,lambda表达式也是一个函数对象。但是在这里,我们所讲的是一种特殊的函数对象,这种函数对象实际上是一个结构体或类的实例,只不过这个结构体或类重载了函数调用符"()"。STL里有自己的仿函数,greater()和less(),我们这里要做的就是重写一个仿函数来代替它们。函数对象的重写也有两种写法:一种是写在自定义结构体的内部,另一种是写在自定义结构体的外部。值得一说的是,使用这种方法,函数签名末尾的const修饰可有可无。这是因为末尾的const代表了不会修改结构体内部变量的值,这和我们要用到的功能毫无关系,因此可以忽略。
第一种:写在类内部:
class Node {
public:
int x_, y_;
Node(int x, int y) :x_(x), y_(y) {}
// 重写仿函数(写在类内部)
bool operator()(Node& a, Node& b) const { // 返回true,表示this的优先级小于a
// x大的排在前面;x相同时,y大的排在前面
if (a._x == b._x) {
return a._y > b._y;
}
return a._x > b._x;
}
}
int main() {
// 待排序数组
vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
sort(vec.begin(), vec.end(), Node()); // 排序
}
第二种:写在类外部
class Node {
public:
int x_, y_;
Node(int x, int y) :x_(x), y_(y) {}
};
// 重写仿函数(写在类外部)
class cmp {
public:
bool operator()(Node a, Node b) { // 返回true,表示this的优先级小于a
// x大的排在前面;x相同时,y大的排在前面
if (a.x_ == b.x_) {
return a.y_ > b.y_;
}
return a.x_ > b.x_;
}
};
int main() {
// 待排序数组
vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
sort(vec.begin(), vec.end(), cmp()); // 排序
}
3. 函数指针
函数指针:通过编写一个外部的比较函数,实现 <
方法,然后将函数指针传入。
class Node {
public:
int x_, y_;
Node(int x, int y) :x_(x), y_(y) {}
}
// 3.函数指针
bool cmp1(Node& a, Node& b) { // 返回true,表示this的优先级小于a
// x大的排在前面;x相同时,y大的排在前面
if (a._x == b._x) {
return a._y > b._y;
}
return a._x > b._x;
}
int main() {
// 待排序数组
vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
sort(vec.begin(), vec.end(), cmp1); // 排序
}
4. lambda表达式
对于sort()
,可以直接使用lambda
表达式代替仿函数。
class Node {
public:
int x_, y_;
Node(int x, int y) :x_(x), y_(y) {}
}
// 4.lambda表达式
auto cmp2 = [](Node& a, Node& b) {return a._x == b._x ? a._y > b._y :a._x > b._x; };
int main() {
// 待排序数组
vector<Node> vec{ Node(10,20),Node(20,10),Node(10,10) };
sort(vec.begin(), vec.end(), cmp2); // 排序
}