👉 “Offer 驾到,掘友接招!我正在参与2022春招打卡活动点击查看 活动详情。
本文已参与「新人创作礼」活动,一起开启掘金创作之路。
lambda 表达式和 std::function
Lambda是匿名函数的别称。从本质上讲,它们是一种在代码的逻辑位置编写函数(比如回调函数)的简单方法。
[capture]: 捕获列表 - 捕捉列表总是出现在Lambda函数的开始处。实际上,[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数。捕捉列表能够捕捉上下文中的变量以供Lambda函数使用;(parameters): 参数列表 – 与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号“()”一起省略;{statement}: 函数体 – 内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
vector<int> v{1,3,2,4};
std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
std::function
std::function 是一个模板化对象,用于存储和调用任何可调用类型,例如函数、对象、lambda 和 std::bind 的结果。
- Ex1 code:
//调用cmp和lambda都可以完成排序,显然lambda写起来更方便
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(int a, int b) { return a < b; }
void output(vector<int>& v) { for(auto val : v) cout << val << " "; cout << endl; }
int main () {
vector<int> v{1,4,7,2,5,8,9,6,3};
output(v);
sort(v.begin(), v.end(), cmp); //调用cmp
sort(v.begin(), v.end(), [](int a, int b) { return a < b; } ); //lambda表达式 int a, int b 也可以换为auto a, auto b
output(v);
return 0;
}
- Ex2 code:
//lambda 和 function的应用,可以将一些函数直接定义在函数体内,采用引用捕获,可以避免传参
#include <iostream>
#include <functional>
using namespace std;
int main() {
int a = 3, b = 4;
//Lambda表达式
auto check = [](int x, int y) {
return x >= 0 && x <= 5 and y >= 0 && y <= 5;
};
//std::function
function<bool(int, int)> check_ = [](int x, int y) {
return x >= 0 && x <= 5 and y >= 0 && y <= 5;
};
//避免传参
auto check__ = [&]() {
return a >= 0 && a <= 5 and b >= 0 && b <= 5;
};
if(check(a, b)) cout << "Y\n";
else cout << "N\n";
if(check_(a, b)) cout << "Y\n";
else cout << "N\n";
if(check__()) cout << "Y\n";
else cout << "N\n";
return 0;
}
//output: Y Y Y
例如在Leetcode上的 437. 路径总和 III
//传统的写法
class Solution {
public:
unordered_map<int,int> mp;
int ans;
int pathSum(TreeNode* root, int sum) {
if(!root) return 0;
ans = 0;
mp[0] = 1;
dfs(root, sum, 0);
return ans;
}
void dfs(TreeNode* root, int sum, int cur){
if(!root) return;
cur += root->val;
if(mp.count(cur - sum)) ans += mp[cur - sum];
mp[cur]++;
dfs(root->left, sum, cur);
dfs(root->right, sum, cur);
mp[cur]--;
}
};
可以采用function写起来更简洁:
//采用function的写法
class Solution {
public:
int pathSum(TreeNode* root, int sum) {
if(!root) return 0;
unordered_map<int,int> mp;
int ans = 0;
mp[0] = 1;
//function
function<void(TreeNode*, int)> dfs = [&](TreeNode* root, int cur) {
if(!root) return;
cur += root->val;
if(mp.count(cur - sum)) ans += mp[cur - sum];
mp[cur]++;
dfs(root->left, cur);
dfs(root->right, cur);
mp[cur]--;
};
dfs(root, 0);
return ans;
}
};