lambda表达式
lambda函数,也叫lambda表达式(简称为lambda),是C++11提供的一种匿名函数-即无需给函数命名。在C++11中,对于接受函数指针或函数符(函数对象)的函数,可使用匿名函数定义(lambda)作为其参数。
lambda语法
Lambda表达式语法:[捕获列表] (参数列表)修饰符->返回值类型{函数体};
捕获列表:[]是lambda的引出符,编译器根据引出符判断接下来是否为lambda表达式。[]中的内容是lambda捕获上下文中的变量(一般为{}作用域中可见的变量)。只有进行捕获才可以在lambda式中使用该变量,捕获的变量一般以逗号分隔,捕获的形式如下:
[]:不对任何变量进行捕获。
[=]:按值传递的方式捕获作用域中所有的变量(类似于值传递函数参数)。
[&]:按引用传递的方式捕获作用域中所有的变量(类似于引用传递函数参数)。
[var]:按值捕获变量var,只捕获具体变量var。
[&var]:按引用捕获变量var,只捕获具体变量var。
[=, &var1,&var2]:按引用捕获var1,var2,按值捕获其他可见变量。需要将=放在最前面,否则报错。
[&, var1,var2]:按值捕获var1,var2,按引用捕获其他可见变量。需要将&放在最前面,否则报错。
注:[=,var]和[&,&var]这种形式编译器也会报错,显示捕获与默认设置匹配。
参数列表:参数列表的含义与函数一致,该部分是可选的,也就是说如果我们不需要参数,可将"()"一起省略。
修饰符:默认情况下,lambda表达式有const修饰,也就是说无法调用非const函数也无法修改值捕获的变量。若在修饰符部分加上关键字mutable,可以取消其常量性。该部分也是可选的。
返回值类型:该部分是可选的,默认情况下,lambda表达式可以自动推断出返回值类型,下面例子lambda可以推断返回值为int,所以不需要显示表明返回值类型。
auto fc = [=]() {
return 8;
};
下面例子既返回int又返回double,lambda无法推断返回值类型,因此需要显示表明返回值类型。
auto fc = [=]()->int{
if (1) {
return 8;
} else {
return 0.8;
}
};
函数体:就是lambda要实现的内容,除了既可以使用参数列表的变量也可以使用捕获列表的变量,其他与函数一样。
注:lambda表达式可以赋值给auto变量。lambda是一条语句,记得加分号。
lambda示例
示例1,按值捕获,不允许修改捕获的值,不允许调用非常函数,捕获类对象时候会进行拷贝构造。
#include <iostream>
#include <string>
using namespace std;
class MyClass
{
public:
MyClass(){ }
~MyClass(){};
void show() {}
public:
int m_a = 66;
};
int main()
{
MyClass a;
MyClass *b = new MyClass;
int c = 88;
auto fc1 = [=]() {
//不允许修改按值捕获,不允许调用非常函数
//c = 80;
//a.m_a = 6;
//a.show();
//按值捕获的指针b不可修改,可以修改b指向的空间
b->m_a = 77;
b->show();
cout << a.m_a << " " << b->m_a << " " << c << endl;;
};
fc1();
return 0;
}
输出为:
66 77 88
示例2,mutable修饰符,在内部可以修改捕获的变量,不会影响外部变量。
int main()
{
MyClass a;
MyClass *b = new MyClass;
int c = 88;
auto fc1 = [=]()mutable{
//加上修饰符mutable可以修改按值捕获,调用非常函数
//但仍是值传递,外部变量不会发生改变
//b是捕获指针变量无法改变,但可以改变b指向空间
c = 8;
a.m_a = 6;
a.show();
b->m_a = 7;
b->show();
cout << a.m_a << " " << b->m_a << " " << c << endl;
};
fc1();
cout << a.m_a << " " << b->m_a << " " << c << endl;
return 0;
}
输出为:
6 7 8
66 7 88
示例3,按引用捕获,修改的就是外部变量本身。
int main()
{
MyClass a;
MyClass *b = new MyClass;
int c = 888;
auto fc1 = [&]() {
//按引用捕获,修改之后,外部变量本身发生改变
c = 8;
a.m_a = 6;
a.show();
b->m_a = 7;
b->show();
cout << a.m_a << " " << b->m_a << " " << c << endl;
};
fc1();
cout << a.m_a << " " << b->m_a << " " << c << endl;
return 0;
}
输出为:
6 7 8
6 7 8