C++ Lambda表达式:从入门到精通
·
一、Lambda 表达式简介
Lambda 表达式是 C++11 标准引入的特性,用于创建匿名函数对象(闭包)。它允许你在代码中直接定义一个函数,而无需显式命名。基本语法结构如下:
[capture](parameters) mutable -> return_type {
// 函数体
}
各部分含义:
[capture](捕获列表):定义 Lambda 表达式如何访问外部变量(parameters)(参数列表):与普通函数参数列表类似mutable(可选项):允许修改捕获的值变量(不影响外部变量)-> return_type(可选项):显式指定返回类型{ }(函数体):包含要执行的代码
二、捕获列表详解
捕获方式决定了 Lambda 如何访问外部作用域的变量:
- 值捕获:创建变量副本
int a = 10; auto lambda = [a] { return a * 2; }; // 捕获a的值 - 引用捕获:直接操作原变量
int b = 20; auto lambda = [&b] { b += 5; }; // 通过引用修改b - 隐式捕获:
[=]:捕获所有外部变量(值方式)[&]:捕获所有外部变量(引用方式)[=, &x]:值捕获所有变量,但x用引用捕获
三、典型应用场景
- STL 算法:
std::vector<int> nums{3,1,4,2}; std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; }); // 降序排序 - 异步编程:
std::thread t([=] { std::cout << "Value captured: " << a << std::endl; }); t.join(); - 延迟执行:
auto defer = [](auto func) { return std::make_shared<std::function<void()>>(func); };
四、C++14/17 增强特性
- 泛型 Lambda(C++14):
auto generic = [](auto x, auto y) { return x + y; }; - constexpr Lambda(C++17):
constexpr auto square = [](int n) { return n * n; }; static_assert(square(5) == 25);
五、注意事项
- 生命周期管理:引用捕获需确保被引对象生命周期长于 Lambda
- 返回值推导:当函数体含多条语句时建议显式声明返回类型
- mutable 修饰:若需修改值捕获的副本必须使用
mutableint counter = 0; auto inc = [counter]() mutable { return ++counter; }; // 修改副本
六、示例:自定义比较器
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<std::string> words{"apple", "banana", "cherry"};
// 按长度排序
std::sort(words.begin(), words.end(),
[](const std::string& a, const std::string& b) {
return a.length() < b.length();
});
for (const auto& w : words) {
std::cout << w << " ";
}
// 输出:apple cherry banana
}
Lambda 表达式极大提升了代码的灵活性和简洁性,是现代 C++ 开发的核心工具之一。
好的,我们来详细讲解 C++ 中的 Lambda 表达式。
一、Lambda 表达式简介
Lambda 表达式是 C++11 标准引入的特性,用于创建匿名函数对象(闭包)。它允许你在代码中直接定义一个函数,而无需显式命名。基本语法结构如下:
[capture](parameters) mutable -> return_type {
// 函数体
}
各部分含义:
[capture](捕获列表):定义 Lambda 表达式如何访问外部变量(parameters)(参数列表):与普通函数参数列表类似mutable(可选项):允许修改捕获的值变量(不影响外部变量)-> return_type(可选项):显式指定返回类型{ }(函数体):包含要执行的代码
二、捕获列表详解
捕获方式决定了 Lambda 如何访问外部作用域的变量:
- 值捕获:创建变量副本
int a = 10; auto lambda = [a] { return a * 2; }; // 捕获a的值 - 引用捕获:直接操作原变量
int b = 20; auto lambda = [&b] { b += 5; }; // 通过引用修改b - 隐式捕获:
[=]:捕获所有外部变量(值方式)[&]:捕获所有外部变量(引用方式)[=, &x]:值捕获所有变量,但x用引用捕获
三、典型应用场景
- STL 算法:
std::vector<int> nums{3,1,4,2}; std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; }); // 降序排序 - 异步编程:
std::thread t([=] { std::cout << "Value captured: " << a << std::endl; }); t.join(); - 延迟执行:
auto defer = [](auto func) { return std::make_shared<std::function<void()>>(func); };
四、C++14/17 增强特性
- 泛型 Lambda(C++14):
auto generic = [](auto x, auto y) { return x + y; }; - constexpr Lambda(C++17):
constexpr auto square = [](int n) { return n * n; }; static_assert(square(5) == 25);
五、注意事项
- 生命周期管理:引用捕获需确保被引对象生命周期长于 Lambda
- 返回值推导:当函数体含多条语句时建议显式声明返回类型
- mutable 修饰:若需修改值捕获的副本必须使用
mutableint counter = 0; auto inc = [counter]() mutable { return ++counter; }; // 修改副本
六、示例:自定义比较器
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<std::string> words{"apple", "banana", "cherry"};
// 按长度排序
std::sort(words.begin(), words.end(),
[](const std::string& a, const std::string& b) {
return a.length() < b.length();
});
for (const auto& w : words) {
std::cout << w << " ";
}
// 输出:apple cherry banana
}
Lambda 表达式极大提升了代码的灵活性和简洁性,是现代 C++ 开发的核心工具之一。
更多推荐

所有评论(0)