三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

C++ Lambda表达式使用

C++ Lambda表达式使用

Lambda 表达式基本语法

C++ Lambda 表达式的基本结构如下:

[capture](parameters) -> return_type { body }
  • [capture]:捕获列表,指定外部变量的捕获方式(值捕获、引用捕获等)。
  • (parameters):参数列表,与普通函数参数一致(C++14 支持auto泛型参数)。
  • -> return_type:可选的返回类型声明(省略时由编译器自动推导)。
  • { body }:函数体,实现具体逻辑。

最小 Lambda 示例

auto print = [] { std::cout << "Hello, Lambda!"; }; print(); // 输出:Hello, Lambda!

捕获列表的用法

捕获列表控制 Lambda 访问外部变量的方式:

值捕获(复制变量):

int x = 10; auto lambda = [x] { return x + 1; }; // 捕获 x 的副本

引用捕获(直接操作原变量):

int y = 20; auto lambda = [&y] { y += 5; }; // 修改原变量 y lambda(); // y 变为 25

混合捕获

int a = 1, b = 2; auto lambda = [a, &b] { return a + b; }; // a 值捕获,b 引用捕获

隐式捕获

  • [=]:以值捕获所有外部变量。
  • [&]:以引用捕获所有外部变量。
  • [=, &x]:默认值捕获,仅x引用捕获。

与 STL 算法结合

Lambda 常用于简化 STL 算法的调用,例如std::sortstd::for_each

std::vector<int> nums = {3, 1, 4, 1, 5}; std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; }); // nums 变为 {5, 4, 3, 1, 1}

生命周期与悬垂引用风险

若 Lambda 捕获引用且原始变量已销毁,后续调用会引发未定义行为:

std::function<int()> createLambda() { int z = 30; return [&z] { return z; }; // 危险:z 是局部变量 } auto f = createLambda(); f(); // 错误:z 已销毁

性能优化建议

  • 优先使用auto存储 Lambda:避免std::function的间接调用开销。
  • 无捕获 Lambda 可转换为函数指针:适用于 C 接口回调。
  • 避免过度捕获:仅捕获必要变量以减少对象大小。

高级特性(C++14/17)

泛型 Lambda(C++14):

auto adder = [](auto a, auto b) { return a + b; }; adder(3, 4.5); // 返回 7.5

初始化捕获(C++14):

int x = 10; auto lambda = [y = x + 1] { return y; }; // y 初始化为 x + 1

constexprLambda(C++17):

constexpr auto square = [](int n) { return n * n; }; static_assert(square(5) == 25); // 编译期计算


← 返回列表