Lambda表达式简介
Lambda表达式是现代C++在C++11和更高版本中的一个新的语法糖。它是一种定义匿名函数对象的便捷方法,常用于封装传递给算法或异步方法的几行代码。Lambda表达式可以在调用或作为函数参数传递的位置处定义,可以捕获上下文中的变量供函数使用。Lambda表达式的语法定义包括捕获列表、参数列表、可变规格、异常说明、返回类型和函数体。捕获列表描述了Lambda函数可以访问的上下文变量及传递方式,参数列表类似于普通函数的参数列表,可变规格用于取消Lambda函数的常量性,异常说明用于指示Lambda函数是否会引发异常,返回类型可以省略让编译器推导,函数体可以包含任意内容。Lambda表达式的优点包括在需要调用函数的位置定义短小精悍的函数,代码紧凑且可读性高。缺点是语法相对灵活增加了阅读难度,对于函数复用有限。Lambda表达式的工作原理是编译器会把Lambda表达式生成一个匿名类的匿名对象,并在类中重载函数调用运算符,实现了一个operator()方法。这样可以用Lambda表达式构造一个函数对象。
在C语言中,没有直接支持Lambda表达式的语法。 Lambda表达式是C++11引入的新特性,它允许在函数调用或作为函数参数传递的位置定义匿名函数对象。C++的Lambda表达式的语法定义与函数定义相似,一般形式为:
[捕获列表](参数列表) mutable noexcept -> 返回类型 {函数体}
示例 1 :
int main()
{
// 两个数相加的lambda
auto add1 = [](int a, int b)->int{return a + b; };
cout << add1(1, 2) << endl;
// 省略返回值
auto add2 = [](int a, int b){return a + b; };
cout << add2(1, 2) << endl;
return 0;
}
示例2
int main()
{
// 交换变量的lambda
int x = 0, y = 1;
auto swap1 = [](int& x1, int& x2)->void {int tmp = x1; x1 = x2; x2 = tmp; };
swap1(x, y);
cout << x << ":" << y << endl;
auto swap2 = [](int& x1, int& x2)
{
int tmp = x1;
x1 = x2;
x2 = tmp;
};
swap2(x, y);
cout << x << ":" << y << endl;
// 不传参数交换x y的lambda -- 捕捉列表
// 默认捕捉的对象不能修改
/*auto swap3 = [x, y]()mutable
{
int tmp = x;
x = y;
y = tmp;
};
swap3();
cout << x << ":" << y << endl;*/
auto swap4 = [&x, &y]
{
int tmp = x;
x = y;
y = tmp;
};
swap4();
cout << x << ":" << y << endl;
return 0;
}
int main()
{
int a = 9;
[]() {cout << a << endl; };
system("pause");
return 0;
}
int main()
{
int a = 9;
auto lam = [a]() {cout << a << endl; };
lam();
return 0;
}
#include
using namespace std;
int main()
{
int a = 9;
int b = 5;
int &x = b;
x = 8;
auto lam = [a, &]()
{
cout << a << " " <
int main()
{
int a = 9;
string s = "hello";
auto lam = [=]() {cout << a << " "<
int main()
{
int a = 9;
auto lam = [&a]() {a = 10; cout << a << endl; };
lam();
return 0;
}
int main()
{
int a = 9;
string s = "hello";
auto lam = [&, a]() {s = "hhah"; cout << a << " " << s << endl; };
lam();
return 0;
}
int main()
{
int a = 9;
string s = "hello";
auto lam = [=, &a]() {a = 90; cout << a << " " << s << endl; };
lam();
return 0;
}
需要注意的是,捕获列表不允许变量重复传递,否则会导致编译时错误。
//捕捉列表的参数来源范围--当前栈帧 (注意全局变量)
int func()
{
int a, b, c, d, e;
a = b = c = d = e = 1;
// 全部传值捕捉
auto f1 = [=](){
cout << a << b << c << d << e << endl;
};
f1();
// 混合捕捉
auto f2 = [=, &a](){
a++;
cout << a << b << c << d << e << endl;
};
f2();
static int x = 0;
if (a)
{
auto f3 = [&, a](){
//a++;//error
b++;
c++;
d++;
e++;
val++;
x++;
cout << a << b << c << d << e << endl;
};
f3();
}
return 0;
}
int main()
{
//error
//auto f4 = [&, a](){
// //a++;
// b++;
// c++;
// d++;
// e++;
// f++;
// cout << a << b << c << d << e << endl;
//};
//f4();
return 0;
}
Lambda表达式可以接受不同类型的参数,具体取决于功能接口中声明的方法的参数类型。参数可以是基本类型、对象类型、函数式接口类型或泛型类型。Lambda表达式的参数列表可以为空,也可以有一个或多个参数。参数列表需要用圆括号括起来,多个参数之间用逗号分隔。当只有一个参数时,可以省略圆括号。Lambda表达式的参数可以在箭头符号(->)之前进行定义,并在表达式中使用。例如:(int a, int b) -> a + b 是接受两个整数参数并返回它们的和的Lambda表达式。总之,Lambda表达式提供了一种简洁的方式来传递行为作为参数,并且可以接受不同类型的参数。123
Lambda表达式的返回类型是通过上下文推导得出的。根据Java语言规范,当Lambda表达式只有一条语句时,会自动推导返回类型。如果Lambda表达式有多条语句,则需要显式指定返回类型。 在Lambda表达式的语法中,返回类型通常是可以省略的,编译器会根据上下文自动推导出返回类型。 Lambda表达式的返回类型推导是通过invokedynamic指令实现的。
123
class Rate
{
public:
Rate(double rate) : _rate(rate)
{}
double operator()(double money, int year)
{
return money * _rate * year;
}
private:
double _rate;
};
//lambda_uuid
//uuid--Universally Unique Identifier,即通用唯一识别码。
class lambda_xxxx
{
};
int main()
{
// 函数对象
double rate = 0.49;
Rate r1(rate);
r1(10000, 2);
// 仿函数lambda_uuid
// lambda -> lambda_uuid
auto r2 = [=](double monty, int year)->double{return monty*rate*year; };
r2(10000, 2);
auto r3 = [=](double monty, int year)->double{return monty*rate*year; };
r3(10000, 2);
return 0;
}