在学校上安卓移动应用开发课程的时候老师给我们提了一下c++lambda表达式,我觉得很有意思,以前没有见过,于是特地在网上搜了很多关于c++lambda,然后我就把我所研究的看到的关于c++lambda的知识点整理起来,弄成了这个微型技术博客。
lambda表达式是C++11最重要也最常用的一个特性之一。lambda来源于函数式编程的概念,也是现代编程语言的一个特点
lambda表达式有如下优点:
1).声明式编程风格:就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者函数对象。以更直接的方式去写程序,好的可读性和可维护性。
2).简洁:不需要额外再写一个函数或者函数对象,避免了代码膨胀和功能分散,让开发者更加集中精力在手边的问题,同时也获取了更高的生产率。
3).在需要的时间和地点实现功能闭包,使程序更灵活。
lambda表达式的语法归纳如下:
[ caputrue ] ( params ) opt -> ret { body; };
1).capture是捕获列表;
2).params是参数表;(选填)
3).opt是函数选项;可以填mutable,exception,attribute(选填)
mutable说明lambda表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获的对象的non-const方法。
exception说明lambda表达式是否抛出异常以及何种异常。
attribute用来声明属性。
4).ret是返回值类型。(选填)
5).body是函数体。
捕获列表:lambda表达式的捕获列表精细控制了lambda表达式能够访问的外部变量,以及如何访问这些变量。
1).[]不捕获任何变量。
2).[&]捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。
3).[=]捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。
4).[=,&foo]按值捕获外部作用域中所有变量,并按引用捕获foo变量。
5).[bar]按值捕获bar变量,同时不捕获其他变量。
6).[this]捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。如果已经使用了&或者=,就默认添加此选项。捕获this的目的是可以在lamda中使用当前类的成员函数和成员变量。
下面是一些部分零碎的测试代码。
void test(Func f){
std::cout<<f(3)<<std::endl;
}
template<typename Func>
void test2(Func f){
std::cout<<f(13)<<std::endl;
}
int main(){
int a = 1;
int b = 2;
auto f = [a,b](int c){return a+b+c;};
test(f);
a=2;b=3;
test2(f);
return 0;
}
这段代码中创建了一个non-mutable lambda。使用了类型自动推断,f的类型编译器会自动计算出来。[]称为capture list,里面的a和b的值同main里面的a和b的值是一样的。
实例:将一个 lambda 传递给 for_each 函数。该 lambda 打印一个结果,该结果指出 vector 对象中的每个元素是偶数还是奇数。
int main()
{
vector<int> v;
for (int i = 1; i < 10; ++i) {
v.push_back(i);
}
int evenCount = 0;
for_each(v.begin(), v.end(), [&evenCount] (int n) {
cout << n;
if (n % 2 == 0) {
cout << "is even" << endl;
++evenCount;
} else {
cout << "is odd" << endl;
}
});
cout << "There are " << evenCount
<< " even numbers in the vector." << endl;
}
#include <iostream>
int main()
{
using namespace std;
int timestwoplusthree = [](int x) { return [](int y) { return y * 2; }(x) + 3; }(5);
//lambda表达式
cout << timestwoplusthree << endl;
//屏幕输出结果
}
在函数中显式使用 this 指针:
void ApplyScale(const vector<int>& v) const
{
for_each(v.begin(), v.end(),
[this](int n) { cout << n * _scale << endl; });
}
可以隐式捕获 this 指针:
void ApplyScale(const vector<int>& v) const
{
for_each(v.begin(), v.end(),
[=](int n) { cout << n * _scale << endl; });
}