// 时间:2023年4月20日时间
// 知识点:Lambda 表达式
请你说说,Lambda表达式用法及实现原理?
1. 什么是 Lambda表达式?
lambda 本质上就是一个简单的,不需要函数名的函数。
2. Lambda 的基本格式是什么?
其基本格式为:
[捕获参数](函数参数){函数体};
eg:
auto fun = [](){ std::cout << "Hello Lambda" << std::endl; };
3. Lambda 表达式能不能赋值给变量,如果可以,赋值后如何调用?
可以赋值,Lambda 表达式的返回值是一个函数指针,赋值后该变量可以当作函数指针来调用。
int main(void) {
auto fun = [](){ cout << "Hello World!" << endl; };
fun();
return 0;
}
即便是不赋值,Lambda表达式依旧可以当作一个函数来调用。
int main(void) {
// Function point
[](){ cout << "Hello World!" << endl; };
// Call function
[](){ cout << "Hello World!" << endl; }();
return 0;
}
后面不加 () 的 Lambda 表达式相当于函数指针,加上 () 就相当于调用这个 Lambda 函数。
4. Lambda表达式可不可以传递参数?
可以
eg:
int main(void) {
int num = 100;
// 为 Lambda 定义一个 int 类型的参数
auto fun = [](int num) { num = 5; cout << num << endl; };
fun(num);
cout << num << endl; //the output is 100
return 0;
}
Lambda 表达式的参数列表就是调用时传递的参数。第二次调用后输出的数值是 100
5. Lambda 表达式捕获参数是什么意思?如何用?
所谓捕获参数,就是调用之前的变量的意思。
Lambda 表达式的 [] 用来确定捕获参数:
1. [=] : 捕获的局部变量只可读不可写,捕获范围是当前 Lambda 表达式之前的作用域。
2. [&] : 捕获的局部变量可读可写。
eg:
int main(void) {
int num = 100;
// read only
auto fun1 = [=]() { cout << num << endl; };
//auto fun1 = [=]() { num = 50; cout << num << endl; }; // 会报错,编译就不过。
fun1();
// read and write
auto fun2 = [&num]() { num = 200; cout << num << endl; };
fun2();
cout << num << endl;// the output is 200
return 0;
}
如果用 [=] 再对调用的变量进行修改,会报错,编译就不过。
6. Lambda表达式可以用在类中吗?如果可以,如何捕获 this ?
可以用在类中,使用 [this] 来捕获 this(感觉像废话一样,但是就是这样。),使用 [&] 捕获所有父作用域的引用,包括 this
void MyClass::function() {
// 使用 [this] 来捕获 this
auto fun1 = [this](int v){cout << v + this->num << endl; };
// 使用 [&] 捕获所有父作用域的引用,包括 this
auto fun2 = [&](int v){cout << v + this->num << endl; };
}
7. 例子:
int main() {
vector<int> vec = { 1, 2, 3, 4, 5 };
// 定义 Lambda
auto fun = [](int num) { cout << num << endl; };
//std::for_each(vec.begin(), vec.end(), fun);
// 将 vec 中的元素都加 1,修改参数必须传递参数的引用
for_each(vec.begin(), vec.end(), [](int& num) { num += 1; });
for_each(vec.begin(), vec.end(), fun); // the output is 2 3 4 5 6
return 0;
}
注:
1. Lambda 是 const 函数
Lambda 默认是 const 函数,不能修改引用的变量,使用 mutable 可以取消该属性,但是 mutable 修改的只是副本。
eg:
int main(void) {
int num = 100;
// Lamnda is const function, use `mutable` can cancel const
//auto fun = [=](){ num = 200; cout << num << endl; };
auto fun = [=]() mutable { num = 200; cout << num << endl; };
fun();
// num = 100
cout << num << endl;
return 0;
}
2. Lambda 没有地址
Lambda 表达式是内联展开的,没有实际的地址,这是与普通函数的一个很大的区别。
int main(void)
{
string str;
auto fun = [](string str) {cout << str << endl; };
cin >> str;
fun(str);
//lambda表达式没有地址,是内联展开的
//cout << (void*)fun << endl; // 会出错,编译不过。
return 0;
}
想要输出函数的地址,会报错,编译不过。
参考文献:
https://www.jianshu.com/p/a200a2dab960
免责声明:
本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。