C++
在 C++ 中,Lambda 表达式(也称为匿名函数或闭包)是一个可以捕获局部变量的简短函数对象。Lambda 表达式可以定义在任何需要函数对象或可调用对象的地方,它们特别适用于需要定义小型、一次性的函数对象的情况。
下面是一个 Lambda 表达式的基本结构和解析:
1.基本语法
[capture](parameters) -> return-type { body }
- [capture]: 捕获子句,用于指定 Lambda 表达式体中可以使用哪些外部变量(按值或按引用)。
- (parameters): 参数列表,与普通函数相同。
- -> return-type: 可选的返回类型说明符,用于指定 Lambda 表达式的返回类型。如果 Lambda 表达式的体只包含一个返回语句,并且编译器能够推断出返回类型,则可以省略该部分。
- { body }: Lambda 表达式的主体,包含函数体的代码。
2.捕获子句
捕获子句决定了哪些外部变量可以在 Lambda 表达式的体内被访问。捕获可以是按值(=)或按引用(&),或者是显式指定变量(例如 [x, &y])。
-
[]
:不捕获任何变量。 -
[=]
:以值捕获所有外部变量。 -
[&]
:以引用捕获所有外部变量。 -
[x, &y]
:按值捕获x
,按引用捕获y
。
3.使用示例
简单的Lambda表达式
这里定义了一个没有捕获任何外部变量的Lambda表达式,并在定义后立即调用。
[] { std::cout << "Hello, World!<<std::endl"; }();
捕获外部变量
在这个例子中,a
被值捕获,b
被引用捕获。Lambda表达式内部可以修改b
的值。
int a = 1;
int b = 2;
auto lambda = [a, &b]() { b = a + b; };
lambda();
std::cout << b; // 输出 3,因为a被值捕获,b被引用捕获
使用捕获列表
Lambda表达式捕获了x
的值,并在调用时将其与参数y
相加。
int x = 10;
auto lambda = [x](int y) { return x + y; };
std::cout << lambda(5); // 输出 15
使用默认捕获
[=]
表示默认以值的方式捕获所有外部变量。
int x = 10, y = 20;
auto lambda = [=](int z) { return x + y + z; };
std::cout << lambda(5); // 输出 35
使用mutable关键字
默认情况下,值捕获的变量在Lambda内部是常量。如果需要修改它们,可以使用mutable
关键字。
int count = 0;
auto lambda = [count]() mutable { return ++count; };
std::cout << lambda() << std::endl; // 输出 1
std::cout << lambda() << std::endl; // 输出 2
即使count
被值捕获,mutable
关键字允许我们在Lambda内部修改它。
使用尾返回类型
如果Lambda表达式的返回类型无法自动推导,或者返回类型比较复杂,可以使用尾返回类型。这里显式指定了Lambda表达式的返回类型为int
。
auto lambda = [](int a, int b) -> int { return a + b; };
std::cout << lambda(5, 3); // 输出 8
Lambda 表达式提供了一种简洁、灵活的方式来定义和使用小型函数对象,使 C++ 代码更加简洁和易读。
Qt
1.基本语法
在Qt中,Lambda表达式是一种方便的方式来定义匿名函数,通常用于连接信号和槽以及其他需要函数对象的地方。Lambda表达式提供了一种更简洁的方式来编写函数对象,而不必显式地编写函数定义。下面是对Qt中Lambda表达式的解析:
[ captures ]( parameters ) mutable(optional) noexcept(optional) -> return_type(optional) { body }
- captures: 捕获列表,用于捕获外部变量。可以是值捕获、引用捕获或混合捕获。
- parameters: 参数列表,用于指定Lambda函数的参数。
- mutable: 可选关键字,指示Lambda函数是否可以修改其捕获的变量。
- noexcept: 可选关键字,指示Lambda函数是否不会抛出异常。
- return_type: 可选的返回类型说明符,用于指定Lambda函数的返回类型。
- body: Lambda函数的主体,即函数体。
2.使用示例
Lambda表达式通常用于连接信号和槽,以及在需要函数对象的地方,例如STL算法和标准库函数中。
连接信号和槽
在Qt中,Lambda表达式通常用于连接信号和槽,如下所示:
QObject::connect(&button, &QPushButton::clicked, [&button]() {
// 在Lambda表达式中,我们可以使用捕获的button对象
button.setText("Clicked!");
qDebug() << "Button was clicked!";
});