QT学习(二)C++Lambda 表达式

Lambda 表达式

Lambda 表达式是 C++11 引入的一种 匿名函数 的方式,它允许你在需要函数的地方内联地定义函数,而无需单独命名函数
Lambda 表达式的基本语法如下:
[ capture clause ]( parameters ) -> return_type {
        // 函数体
        // 可以使用捕获列表中的变量
        return expression ; // 可选的返回语句
}

 Lambda 表达式由以下部分组成:

捕获列表( Capture clause :用于捕获外部变量,在 Lambda 表达式中可以访问这些变量。捕
获列表可以为空,也可以包含变量列表 [var1, var2, ...]
参数列表( Parameters :与普通函数的参数列表类似,可以为空或包含参数列表 (param1, param2, ...) 。
返回类型( Return type Lambda 表达式可以自动推断返回类型 auto ,也可以显式指定返回类
-> return_type 。如果函数体只有一条返回语句,可以省略返回类型。
函数体( Body Lambda 表达式的函数体,包含需要执行的代码。
Lambda 表达式最简单的案例是在需要一个小型函数或临时函数时直接使用它。以下是一个非常简单的
例子,其中使用 Lambda 表达式来定义一个加法操作,并立即使用它来计算两个数的和。

示例:使用 Lambda 表达式进行加法

#include <iostream>
int main() {
    // 定义一个简单的 Lambda 表达式进行加法
    auto add = [](int a, int b) {
    return a + b;
    };
    
    // 使用 Lambda 表达式计算两个数的和
    int sum = add(10, 20);
    std::cout << "Sum is: " << sum << std::endl;
    return 0;
}
在这个例子中:
我们定义了一个名为 add Lambda 表达式,它接受两个整数参数,并返回它们的和。
然后,我们使用这个 Lambda 表达式来计算两个数字( 10 20 )的和,并将结果存储在变量 sum
中。
最后,我们打印出这个和。
这个例子展示了 Lambda 表达式的基本用法:作为一种简洁而快速的方式来定义小型函数。
我们可以写一个例子,其中使用一个函数来找出两个数中的较大数,这个函数将接受一个 lambda 函数
作为回调来比较这两个数。 Lambda 函数将直接在函数调用时定义,完全是匿名的。

先回忆以下回调函数

bool myCompare(int a, int b){
    return a > b;
}
int getMax(int a, int b, bool(*compare)(int, int)) {
    if (compare(a, b)) {
        return a;
    } else {
        return b;
}
}
int main() {
    int x = 10;
    int y = 20;
    // 回调函数
    int max = getMax(x, y, myCompare);
    std::cout << "The larger number is: " << max << std::endl;
    return 0;
}

示例:使用匿名 Lambda 函数来返回两个数中的较大数

#include <iostream>
// 函数,接受两个整数和一个比较的 lambda 函数
bool myCompare(int a, int b){
    return a > b;
}
int getMax(int a, int b, bool(*compare)(int, int)) {
    if (compare(a, b)) {
        return a;
    } else {
        return b;
}
}
int main() {
    int x = 10;
    int y = 20;
    // 回调函数 
    int max = getMax(x, y, [](int a,int b){
                return a>b;
    });
    std::cout << "The larger number is: " << max << std::endl;
    return 0;
}
在这个例子中:
getMax 函数接受两个整数 a b ,以及一个比较函数 compare 。这个比较函数是一个指向函数
的指针,它接受两个整数并返回一个布尔值。
main 函数中,我们调用 getMax ,并直接在调用点定义了一个匿名的 lambda 函数。这个
lambda 函数接受两个整数并返回一个表示第一个整数是否大于第二个整数的布尔值。
这个 lambda 函数在 getMax 中被用作比较两个数的逻辑。根据 lambda 函数的返回值, getMax
返回较大的数。
这个例子展示了如何直接在函数调用中使用匿名 lambda 函数,使代码更加简洁和直接。这种方法在需
要临时函数逻辑的场合非常有用,尤其是在比较、条件检查或小型回调中。
Lambda 表达式中,参数捕获是指 Lambda 表达式从其定义的上下文中捕获变量的能力。这使得
Lambda 可以使用并操作在其外部定义的变量。捕获可以按值(拷贝)或按引用进行。
让我们通过一个简单的示例来展示带参数捕获的 Lambda 表达式。

示例:使用带参数捕获的 Lambda 表达式

#include <iostream>
using namespace std;
int main() {
    int x = 10;
    int y = 20;
    // 捕获 x 和 y 以便在 Lambda 内部使用
    // 这里的捕获列表 [x, y] 表示 x 和 y 被按值捕获
    auto sum = [x, y]() {
    // x++;
    // y++; 按值捕获,关注的是值本身,无法修改
    return x + y;
    };
    std::cout << "Sum is: " << sum() << std::endl;
    std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
    // 捕获所有外部变量按值捕获(拷贝)
    int z = 30;
    auto multiply = [=]() {
    // x++;
    // y++; 按值捕获,关注的是值本身,无法修改
    return x * y * z;
    };
    cout << x << "," << y << endl;
    std::cout << "Product is: " << multiply() << std::endl;
    std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
    // 捕获所有外部变量按引用捕获
    auto modifyAndSum = [&]() {
    x = 15; // 修改 x 的实际值
    y = 25; // 修改 y 的实际值, 引用捕获可以修改
    return x + y;
    };
    std::cout << "Modified Sum is: " << modifyAndSum() << std::endl;
    std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
    return 0;
    }
}
在这个例子中:
第一个 Lambda 表达式 sum 按值捕获了 x y (即它们的副本)。这意味着 sum 内的 x y
是在 Lambda 定义时的值的拷贝。
第二个 Lambda 表达式 multiply 使用 [=] 捕获列表,这表示它按值捕获所有外部变量。
第三个 Lambda 表达式 modifyAndSum 使用 [&] 捕获列表,这表示它按引用捕获所有外部变量。
因此,它可以修改 x y 的原始值。
这个示例展示了如何使用不同类型的捕获列表(按值和按引用)来控制 Lambda 表达式对外部变量的访 问和修改。按值捕获是安全的,但不允许修改原始变量,而按引用捕获允许修改原始量,但需要注意 引用的有效性和生命周期问题

以下是一个表格,概述了 Lambda 函数和内联函数在 C++ 中的相似之处和区别:

请注意,虽然 Lambda 函数和内联函数在某些方面有相似之处,如它们都可以被编译器优化以减少调用
开销,但它们在设计和用途上有明显的不同。 Lambda 函数的核心优势在于它们的匿名性和对外部变量
的捕获能力,而内联函数则主要关注于提高小型函数的性能。

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值