Lambda表达式

8 篇文章 0 订阅
3 篇文章 0 订阅

Lambda表达式

C++

在 C++ 中,Lambda 表达式(也称为匿名函数或闭包)是一个可以捕获局部变量的简短函数对象。Lambda 表达式可以定义在任何需要函数对象或可调用对象的地方,它们特别适用于需要定义小型、一次性的函数对象的情况。

下面是一个 Lambda 表达式的基本结构和解析:

  1. 基本语法
[capture](parameters) -> return-type { body }
  • [capture]:捕获子句,用于指定 Lambda 表达式体中可以使用哪些外部变量(按值或按引用)。
  • (parameters):参数列表,与普通函数相同。
  • -> return-type:可选的返回类型说明符,用于指定 Lambda 表达式的返回类型。如果 Lambda 表达式的体只包含一个返回语句,并且编译器能够推断出返回类型,则可以省略该部分。
  • { body }:Lambda 表达式的主体,包含函数体的代码。
  1. 捕获子句

捕获子句决定了哪些外部变量可以在 Lambda 表达式的体内被访问。捕获可以是按值(=)或按引用(&),或者是显式指定变量(例如 [x, &y])。

* `[]`:不捕获任何变量。
* `[=]`:以值捕获所有外部变量。
* `[&]`:以引用捕获所有外部变量。
* `[x, &y]`:按值捕获 `x`,按引用捕获 `y`。
  1. 使用示例
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};

    // 使用 Lambda 表达式对 vector 中的每个元素乘以 2
    std::transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });

    // 输出结果
    for (int i : v) {
        std::cout << i << ' ';
    }

    // 输出:2 4 6 8 10

    return 0;
}

在这个例子中,我们使用了一个简单的 Lambda 表达式 [](int x) { return x * 2; } 作为 std::transform 的第四个参数。这个 Lambda 表达式接受一个整数参数 x,并返回 x * 2

Lambda 表达式提供了一种简洁、灵活的方式来定义和使用小型函数对象,使 C++ 代码更加简洁和易读。

Qt

在Qt中,Lambda表达式是一种方便的方式来定义匿名函数,通常用于连接信号和槽以及其他需要函数对象的地方。Lambda表达式提供了一种更简洁的方式来编写函数对象,而不必显式地编写函数定义。下面是对Qt中Lambda表达式的解析:

[ captures ]( parameters ) mutable(optional) noexcept(optional) -&gt; return_type(optional) { body }
  1. captures:捕获列表,用于捕获外部变量。可以是值捕获、引用捕获或混合捕获。
  2. parameters:参数列表,用于指定Lambda函数的参数。
  3. mutable:可选关键字,指示Lambda函数是否可以修改其捕获的变量。
  4. noexcept:可选关键字,指示Lambda函数是否不会抛出异常。
  5. return_type:可选的返回类型说明符,用于指定Lambda函数的返回类型。
  6. body:Lambda函数的主体,即函数体。

Lambda表达式的使用
Lambda表达式通常用于连接信号和槽,以及在需要函数对象的地方,例如STL算法和标准库函数中。
连接信号和槽
在Qt中,Lambda表达式通常用于连接信号和槽,如下所示:

QObject::connect(sender, &amp;Sender::signal, [](int value) {
    qDebug() &lt;&lt; "Received value:" &lt;&lt; value;
});

这里,Lambda表达式作为槽函数,用于处理信号发出时的操作。
STL算法和标准库函数
Lambda表达式也可以用于STL算法和标准库函数,例如std::sort:

std::vector&lt;int&gt; vec = {3, 1, 4, 1, 5, 9, 2, 6, 5};
std::sort(vec.begin(), vec.end(), [](int a, int b) {
    return a &lt; b;
});

这里,Lambda表达式定义了排序的比较函数。
Lambda表达式与捕获列表
Lambda表达式的捕获列表允许您在Lambda函数内部访问外部变量。捕获列表可以是值捕获、引用捕获或混合捕获。
值捕获

int a = 10;
auto lambda = [a]() {
    qDebug() &lt;&lt; "Captured value:" &lt;&lt; a;
};

在这个例子中,Lambda表达式通过值捕获变量a,这意味着在Lambda函数内部使用的a的值是捕获时的值。
引用捕获

int b = 20;
auto lambda = [&amp;b]() {
    qDebug() &lt;&lt; "Captured reference:" &lt;&lt; b;
};

在这个例子中,Lambda表达式通过引用捕获变量b,这意味着在Lambda函数内部使用的b是外部变量b的引用。
混合捕获

int c = 30;
auto lambda = [c]() mutable {
    qDebug() &lt;&lt; "Captured value before modification:" &lt;&lt; c;
    c = 40;
    qDebug() &lt;&lt; "Captured value after modification:" &lt;&lt; c;
};

在这个例子中,Lambda表达式通过值捕获变量c,但由于指定了mutable关键字,Lambda函数可以修改捕获的变量。
Lambda表达式与返回类型推断
Lambda表达式可以根据其返回语句的类型来推断返回类型,也可以显式指定返回类型。

auto lambda = [](int a, int b) { return a + b; }; // 自动推断返回类型
int sum = lambda(3, 4); // sum = 7

auto lambda2 = [](int a, int b) -&gt; double { return a + b; }; // 显式指定返回类型为double
double result = lambda2(3, 4); // result = 7.0

Lambda表达式与异常规范
Lambda表达式可以指定是否会抛出异常。

auto lambda = []() noexcept {
    qDebug() &lt;&lt; "This lambda will not throw exceptions.";
};

Lambda表达式的限制
虽然Lambda表达式提供了许多方便的功能,但也有一些限制。Lambda函数不能是虚函数,也不能包含goto语句。此外,在Lambda表达式内部不能声明其它的Lambda表达式。

  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值