前言:
其实在Qt以及C++以及其他编码的过程中都会遇到Lambda表达式,回想起来最先接触到Lambda表达式的用法是在学习Python的时候,现在的场景又经常遇到,但是一直没有参悟透,为此将自己的学习和经验记录于此。
理解:
根据简书上一篇博文分享得到的–理解是:
Lambda表达式实现了函数名字和功能的分离,允许在不起名字的情况下定义和使用功能。
举个生活中的例子,点外卖时我们关心的只是外卖小哥送货上门的“功能”,不需要特意记住他的“名字”。
怎么用Lambda表达式?
Lambda表达式的具体语法可以参考cppreference上的Guide。一个Lambda表达式的形式通常为:
[ capture-list ] ( params ) -> ret { body }
其中( params ) -> ret定义了这个匿名函数的参数和返回类型, { body }定义了这个匿名函数的功能,捕捉列表[ capture-list ]是做什么的呢?概括地讲,它使这个匿名函数可以访问外部(父作用域)变量。
还是举个例子:
int main() {
int a = 0;
auto f = ([]()->void {cout << a << endl;});
f();
return 0;
}
这段代码的含义是定义了一个匿名函数赋给f并运行f,但编译时会报错:
error: ‘a’ is not captured
因为变量a在函数f的外部,想要访问a的话需要把它加到[ capture-list ]里,也就是:
int main() {
int a = 0;
auto f = ([a]()->void {cout << a << endl;});
f();
return 0;
}
捕捉方式有按值和按引用两种。比如[a, &b]表示按值捕捉a,按引用捕捉b;[&, a]表示按引用捕捉所有父作用域变量,除了a按值捕捉,[=,&b]表示按值捕捉所有父作用域变量,除了b按引用捕捉。
假设有数组data,想生成只保留data中偶数的新数组result,可以用:
int main() {
vector<int> data;
vector<int> result;
for (int i = 0; i < 10; ++i)
data.push_back(i);
for_each(data.begin(), data.end(), [&result](int &elem){
if (elem % 2 == 0)
result.push_back(elem);
});
for_each(result.begin(), result.end(), [](int &elem){
cout << elem << endl;
});
return 0;
}
Lambda表达式中的this
lambda表达式最终会返回一个实现了指定接口的实例,看上去和内部匿名类很像,但有一个最大的区别就是代码里面的this,内部匿名类this指向的就是匿名类,而lambda表达式里面的this指向的当前类。
参考资料
1.链接:https://www.jianshu.com/p/96e9dba6e7a9
2.链接:https://blog.csdn.net/u010984552/article/details/53634513
3.链接:https://zhuanlan.zhihu.com/p/35843517