C++ 的 lambda 表达式
源于:通义千问
C++ 的 lambda 表达式 是一种定义匿名函数的方式,它允许我们在代码中直接创建简单、轻量级的函数对象,而无需显式地定义一个命名函数或函数对象(functor)。Lambda 表达式是从 C++11 开始引入的,并且在后续版本(如 C++14 和 C++17)中得到了进一步增强。
一、Lambda 表达式的语法
Lambda 表达式的基本语法如下:
[capture](parameters) -> return_type { body }
各部分含义:
-
[capture]
- 捕获列表,用于捕获外部变量。
- 可以捕获局部变量、类成员变量等。
- 常见的捕获方式有:
[]
:不捕获任何变量。[=]
:按值捕获所有外部变量。[&]
:按引用捕获所有外部变量。[x, &y]
:按值捕获x
,按引用捕获y
。[this]
:捕获当前类的this
指针。
-
(parameters)
- 参数列表,类似于普通函数的参数列表。
- 如果没有参数,可以省略括号。
-
-> return_type
- 返回类型,使用尾随返回类型(trailing return type)。
- 如果编译器可以推导出返回类型,则可以省略这部分。
-
{ body }
- 函数体,包含实际执行的代码逻辑。
二、Lambda 表达式的示例
示例 1:简单的 lambda 表达式
#include <iostream>int main() {// 定义一个简单的 lambda 表达式auto greet = []() { std::cout << "Hello, World!" << std::endl; };// 调用 lambda 表达式greet();return 0;
}
输出:
Hello, World!
示例 2:带参数的 lambda 表达式
#include <iostream>int main() {// 定义一个带参数的 lambda 表达式auto add = [](int a, int b) -> int { return a + b; };// 调用 lambda 表达式int result = add(3, 5);std::cout << "Result: " << result << std::endl;return 0;
}
输出:
Result: 8
示例 3:捕获外部变量
#include <iostream>int main() {int x = 10, y = 20;// 按值捕获 x,按引用捕获 yauto func = [x, &y]() {std::cout << "x: " << x << ", y: " << y << std::endl;y += 5; // 修改 y 的值};func(); // 调用 lambda 表达式std::cout << "After lambda call, y: " << y << std::endl;return 0;
}
输出:
x: 10, y: 20
After lambda call, y: 25
三、Lambda 表达式的用途
-
作为函数参数
Lambda 表达式经常被用作算法的参数。例如,STL 中的std::sort
、std::for_each
等函数都可以接受 lambda 表达式。#include <iostream> #include <vector> #include <algorithm>int main() {std::vector<int> vec = {5, 2, 8, 1, 9};// 使用 lambda 表达式对 vector 进行排序std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; });for (int num : vec) {std::cout << num << " ";}return 0; }
输出:
9 8 5 2 1
-
简化回调函数
在事件驱动编程中,lambda 表达式可以用作回调函数。 -
实现小型功能
当需要实现一些简单的功能时,使用 lambda 表达式比定义完整函数更方便。
四、Lambda 表达式的高级特性
1. 可变 lambda 表达式
默认情况下,lambda 表达式的函数体是不可变的(即不能修改捕获的值)。如果需要修改捕获的值,可以在参数列表后添加 mutable
关键字。
#include <iostream>int main() {int x = 10;// 按值捕获 x,并允许修改auto func = [x]() mutable {x += 5;std::cout << "Inside lambda, x: " << x << std::endl;};func(); // 调用 lambda 表达式std::cout << "Outside lambda, x: " << x << std::endl;return 0;
}
输出:
Inside lambda, x: 15
Outside lambda, x: 10
注意:由于是按值捕获,外部的 x
不会被修改。
2. 泛型 lambda(C++14)
从 C++14 开始,lambda 表达式可以使用 auto
关键字定义泛型参数。
#include <iostream>int main() {auto print = [](const auto& value) {std::cout << "Value: " << value << std::endl;};print(42); // 整数print(3.14); // 浮点数print("Hello"); // 字符串return 0;
}
3. Lambda 表达式与 std::function
Lambda 表达式可以存储在 std::function
对象中,便于传递和复用。
#include <iostream>
#include <functional>void execute(const std::function<void()>& func) {func();
}int main() {int x = 10;auto lambda = [&x]() { std::cout << "x: " << x << std::endl; };execute(lambda);return 0;
}