侯捷 C++ 课程学习笔记:lambda 表达式在现代 C++ 中的应用

目录

初识 lambda 表达式的困惑

侯捷课程中的关键知识点

lambda 表达式的语法结构

捕获方式

lambda 表达式在现代 C++ 中的优势

代码简洁性

提高代码可读性

增强代码的灵活性

实际项目中的应用案例

图形界面编程

数据处理与分析


在接触侯捷老师的 C++ 课程之前,lambda 表达式对我而言一直是个既新奇又有些晦涩的概念。虽然知晓它在现代 C++ 编程中频繁出现,但对于如何正确运用它,发挥其强大功能,始终一知半解。侯捷老师深入浅出的讲解,让我对 lambda 表达式在现代 C++ 中的应用有了清晰且深入的认识。

初识 lambda 表达式的困惑

初次在代码中见到 lambda 表达式时,其独特的语法结构让人摸不着头脑。例如:

 

auto add = [](int a, int b) { return a + b; };

int result = add(3, 5);

这个看似简洁却又陌生的代码片段,[]、()、{}等符号组合在一起,让人难以理解其含义和用途。在以往的编程经验中,定义函数通常使用传统的函数声明和定义方式,而 lambda 表达式这种全新的表达方式,打破了原有的认知模式,导致在尝试使用时,不知从何下手。

侯捷课程中的关键知识点

lambda 表达式的语法结构

侯捷老师详细介绍了 lambda 表达式的基本语法:[捕获列表](参数列表) mutable -> 返回类型 {函数体}。其中,捕获列表用于捕获外部作用域中的变量,使其在 lambda 表达式内部可用;参数列表与传统函数的参数列表类似,用于接收传入的参数;mutable关键字用于修改按值捕获的变量(若不使用mutable,按值捕获的变量在 lambda 表达式内部是只读的);-> 返回类型指定函数的返回类型,若函数体中只有一条return语句,且编译器能够推断出返回类型,则可以省略该部分;函数体则是具体的实现逻辑。例如:

 

int x = 5;

auto multiplyByX = [x](int a) { return a * x; };

int result = multiplyByX(4); // result为20

在这个例子中,[x]表示按值捕获变量x,(int a)是参数列表,函数体return a * x实现了将传入参数a与捕获的x相乘并返回结果的功能。

捕获方式

课程中重点讲解了 lambda 表达式的捕获方式,包括按值捕获[变量名]、按引用捕获[&变量名]以及混合捕获。按值捕获时,lambda 表达式内部会复制一份捕获变量的值,对该变量的修改不会影响外部变量。按引用捕获则是引用外部变量,在 lambda 表达式内部对变量的修改会反映到外部。混合捕获允许同时使用按值和按引用捕获。例如:

 

int y = 10;

int z = 20;

auto modifyYAndZ = [&y, z](int a) { y += a; return z * a; };

int newZ = modifyYAndZ(5); // newZ为100,y变为15

这里,y是按引用捕获,z是按值捕获,在modifyYAndZ函数中对y的修改会影响外部的y,而z在函数内部是一份拷贝,不影响外部的z。

lambda 表达式在现代 C++ 中的优势

代码简洁性

lambda 表达式极大地简化了代码。在需要定义一些简单的、临时性的函数时,无需像传统方式那样在代码的其他地方专门定义函数,直接在使用处编写 lambda 表达式即可。例如,在使用std::sort对一个std::vector<int>进行降序排序时:

 

#include <iostream>

#include <vector>

#include <algorithm>

int main() {

std::vector<int> numbers = {5, 2, 8, 1, 9};

std::sort(numbers.begin(), numbers.end(), [](int a, int b) { return a > b; });

for (int num : numbers) {

std::cout << num << " ";

}

return 0;

}

通过 lambda 表达式,我们直接在std::sort的第三个参数处定义了比较函数,使代码更加紧凑,无需额外定义一个全局或局部的比较函数。

提高代码可读性

虽然 lambda 表达式语法起初可能较难理解,但在熟悉之后,它能够使代码的意图更加清晰。例如,在使用std::for_each遍历容器并对每个元素执行特定操作时:

 

std::vector<int> values = {1, 2, 3, 4, 5};

std::for_each(values.begin(), values.end(), [](int& num) { num *= 2; });

从这段代码中可以直观地看出,我们对values容器中的每个元素都进行了乘以 2 的操作,lambda 表达式将操作逻辑与遍历操作紧密结合,使代码更易读。

增强代码的灵活性

lambda 表达式可以作为参数传递给函数,这为函数的功能扩展提供了极大的灵活性。例如,在一个自定义的算法函数中,我们可以通过传入不同的 lambda 表达式来实现不同的业务逻辑:

 

void customAlgorithm(const std::vector<int>& data, std::function<void(int)> operation) {

for (int num : data) {

operation(num);

}

}

int main() {

std::vector<int> data = {10, 20, 30};

customAlgorithm(data, [](int num) { std::cout << num * 3 << " "; });

return 0;

}

这里,customAlgorithm函数接受一个std::function<void(int)>类型的参数operation,通过传入不同的 lambda 表达式,我们可以灵活地对data中的每个元素执行不同的操作。

实际项目中的应用案例

图形界面编程

在图形界面编程中,lambda 表达式常用于处理用户事件。例如,在使用 Qt 框架开发一个简单的按钮点击事件时:

 

#include <QApplication>

#include <QPushButton>

#include <iostream>

int main(int argc, char *argv[]) {

QApplication app(argc, argv);

QPushButton button("Click me");

button.clicked.connect([&button]() {

button.setText("Clicked!");

std::cout << "Button clicked" << std::endl;

});

button.show();

return app.exec();

}

通过 lambda 表达式,我们简洁地定义了按钮点击后的操作,包括修改按钮文本和输出日志信息,使代码更加简洁高效。

数据处理与分析

在数据处理与分析场景中,lambda 表达式也发挥着重要作用。例如,在处理一个包含学生成绩的std::vector<Student>容器时,我们需要筛选出成绩大于 80 分的学生:

 

#include <iostream>

#include <vector>

#include <algorithm>

struct Student {

std::string name;

int score;

};

int main() {

std::vector<Student> students = {

{"Alice", 85},

{"Bob", 70},

{"Charlie", 90}

};

std::vector<Student> highScorers;

std::copy_if(students.begin(), students.end(), std::back_inserter(highScorers), [](const Student& student) {

return student.score > 80;

});

for (const auto& student : highScorers) {

std::cout << student.name << ": " << student.score << std::endl;

}

return 0;

}

这里,通过std::copy_if和 lambda 表达式,我们轻松实现了对学生成绩的筛选,lambda 表达式简洁地定义了筛选条件,使代码逻辑清晰明了。

通过学习侯捷老师的课程,我对 lambda 表达式在现代 C++ 中的应用有了全新的认识和掌握。在今后的编程实践中,我将充分利用 lambda 表达式的优势,编写更加简洁、高效且易读的 C++ 代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值