C++的仿函数与Lambda表达式的简单用法
仿函数
仿函数,就是类中重载了()
的类,比如这个:
class Cls {
private:
int x;
public:
bool operator () {
}
};
可以注意到,仿函数作为一个类,也是可以有自己的成员。
一些小用途
在c++中,仿函数可以替代c的回调函数(而且还有带有成员)。比如sort或者是一些stl的容器中可以使用仿函数。
struct Cmp {
bool operator () (const int &x, const int &y) {
return x > y;
}
};
void solve(vector<int>&v) {
sort(v.begin(), v.end(), Cmp);
set<int, Cmp>st;
priority_queue<int, vector<int>, Cmp>q;
}
对于set和map的判重
众所周知,set和map可以判重。里面判重的实际方式为:当目前比较结果为false
时,两个元素将会换个位置再比较一次。如果结果还是false
,那么set和map就会认为这个元素已经是存在了。
所以对于上面那个set的仿函数中,要确保不会出现两个元素交换位置再比较时都出现true
的情况,这种情况下会出现未知问题(很玄学就是了)。
Lambda表达式
要求在C++11及以上。
Lambda表达式,其实是创建了个匿名的仿函数对象(不过实际上并不完全等价)。基本的写法像这样:
[捕获列表](形参对象)函数选项->函数返回值类型 {
函数结构体
};
一般来说,Lambda表达式能够自动推导函数返回结果(除非它推导不出)。
Lambda表达式可以作为一些容器的比较函数,比如下面的例子:
void solve(){
auto cmp = [](const pair<int, int> &a, const pair<int, int> &b){
return a.second == b.second ? a.first < b.first : a.second > b.second;
};
priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)>q(cmp);
}
当然还有一种:
void solve(){
auto cmp = [](const pair<int, int> &a, const pair<int, int> &b){
return a.second == b.second ? a.first < b.first : a.second > b.second;
};
priority_queue<pair<int, int>, vector<pair<int, int>>,
function<bool(const pair<int, int> &a, const pair<int, int>&b)>>q(cmp);
}
还有一些函数,也可以直接使用Lambda表达式,比如下面的sort函数。
void solve(vector<int> &a) {
sort(a.begin(), a.end(), [](const int &a, const int &b) {
return a > b;
});
}