我们在进行sort排序时,通常会根据需求进行从小到大或者从大到小的排序,例如下面代码
class Solution {
public:
//在类里面成员函数没有加static修饰符
bool cmp(vector<int> a, vector<int> b) {
//按二元组第一个数从大到小排序
//如果第一个数相等,则在相等的情况下按第二个数排序
if (a[0] == b[0])return a[1] < b[1];
return a[0] > b[0];
}
void fun(vector<vector<int>> &input) {
//input的每个对象是一个二元组,例如{ {1,0},{2,0},{2,1} }
sort(input.begin(), input.end(), cmp);
}
};
但这样的代码是无法通过的,会出现以下的报错信息:
,
首先是第一个错误,这是因为std::sort函数的第三个参数需要接收一个普通的函数指针,也即一般情况下的函数名,因此bool函数实质上与下面的形式等价:
bool cmp(vector<int> a, vector<int> b) {
if (a[0] == b[0])return a[1] < b[1];
return a[0] > b[0];
}
//函数指针*pf指向函数名cmp
bool(*pf)(vector<int>, vector<int>) = cmp;
而在类里面,指向函数的指针pf必须声明成员函数所在类的作用域,也即必须配合类的对象使用,因此普通的函数指针无法接受类成员函数指针作为参数
class test {
public:
bool cmp(int a,int b) {
return a > b;
}
//此处会报错,因为函数指针bool (*)类型不能接受bool (test::*)类型
bool(*pf)(int ,int ) = cmp;
//此处正确
bool (test::*tf)(int, int) = cmp;
};
第二个问题是传入的函数参数过多,这是因为sort需要接受的自定义函数参数只与sort的前两个参数有关,而成员函数默认具有至少一个参数:this指针,sort(int, int, cmp)要求cmp形参类型为(int,int),因此需要参数过多
class test {
public:
//sort(int, int, cmp)要求cmp形参类型为(int,int)
bool cmp(test *this,int a,int b) {
return a > b;
}
};
值得注意的是,采用static修饰符的成员函数不需要实例化,是属于类本身,因此它没有this指针,也不会出现参数过多的报错;同时由于普通函数指针可以指向静态成员函数,因此传入的参数类型匹配,可有效解决这个问题