欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > c++ lambda

c++ lambda

2025/6/14 4:27:54 来源:https://blog.csdn.net/weixin_45524582/article/details/148583171  浏览:    关键词:c++ lambda

在C++中,lambda表达式是一种匿名函数对象,用于创建临时的、短小的函数。它特别适合作为算法(如sortfind_if)的谓词或回调函数。下面详细介绍其语法、捕获列表、参数列表和返回类型。

一、基本语法

[capture list](parameter list) -> return type {function body
}
各部分说明:
  1. [capture list]

    • 捕获外部变量,使lambda内部可以访问。
    • 示例:
      int x = 10;
      auto add_x = [x](int y) { return x + y; };  // 捕获x的值
      
  2. (parameter list)

    • 与普通函数的参数列表类似,但不能有默认参数。
    • 示例:
      auto sum = [](int a, int b) { return a + b; };  // 接受两个int参数
      
  3. -> return type

    • 返回类型可以省略,编译器会自动推导。
    • 示例:
      auto square = [](int x) -> double { return x * x; };  // 显式指定返回类型为double
      
  4. { function body }

    • 函数体,可以使用捕获的变量和传入的参数。

二、捕获列表(Capture List)

捕获列表用于指定lambda如何访问外部变量,有以下几种方式:

1. 值捕获(By Value)
int x = 5;
auto lambda = [x]() { return x * 2; };  // 捕获x的值
  • 特点:lambda内部使用的是x的副本,修改lambda内部的x不会影响外部变量。
2. 引用捕获(By Reference)
int x = 5;
auto lambda = [&x]() { x *= 2; };  // 捕获x的引用
lambda();  // 执行后,外部的x变为10
  • 特点:lambda内部直接使用外部变量的引用,修改会影响外部变量。
3. 隐式捕获
int x = 1, y = 2;
auto sum = [=]() { return x + y; };  // 以值方式捕获所有外部变量
auto product = [&]() { return x * y; };  // 以引用方式捕获所有外部变量
  • [=]:值捕获所有外部变量。
  • [&]:引用捕获所有外部变量。
4. 混合捕获
int x = 1, y = 2;
auto lambda = [&, x]() { y += x; };  // 引用捕获y,值捕获x
  • 规则:捕获列表中,[&, var]表示除var外以引用捕获,[=, &var]表示除var外以值捕获。

三、参数列表和返回类型

1. 参数列表

与普通函数类似,但不能有默认参数:

auto add = [](int a, int b) { return a + b; };  // 两个int参数
auto identity = [](auto x) { return x; };  // C++14起支持泛型lambda
2. 返回类型
  • 自动推导(推荐):
    auto divide = [](double a, double b) { return a / b; };  // 返回类型为double
    
  • 显式指定(复杂情况):
    auto conditional = [](int x) -> double {return x > 0 ? x : 0.5;  // 返回类型可能是int或double,需显式指定为double
    };
    

四、mutable关键字

默认情况下,值捕获的变量在lambda内部是只读的。使用mutable可以修改值捕获的变量:

int x = 10;
auto lambda = [x]() mutable {x += 5;  // 允许修改值捕获的x的副本return x;
};
std::cout << lambda();  // 输出15
std::cout << x;  // 外部的x仍为10

五、应用场景

1. 作为算法的谓词
std::vector<int> nums = {3, 1, 4, 1, 5};
std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; });  // 降序排序
2. 回调函数
std::function<void()> callback;
{int x = 100;callback = [&x]() { std::cout << x; };  // 危险!引用捕获局部变量x
}  // x已销毁,调用callback会导致未定义行为
3. 延迟执行
auto delayed_sum = [](int a, int b) {return [=]() { return a + b; };  // 返回一个新的lambda
};
auto result = delayed_sum(3, 4);
std::cout << result();  // 输出7

六、注意事项

  1. 捕获生命周期
    引用捕获的变量必须在lambda执行时仍然有效。避免捕获局部变量的引用,除非确保lambda会在局部变量销毁前执行。

  2. 性能考虑

    • 值捕获会复制变量,大型对象建议使用引用捕获。
    • 空捕获列表的lambda可以隐式转换为函数指针。
  3. 泛型lambda(C++14+)
    使用auto作为参数类型,创建类似模板的lambda:

    auto print = [](const auto& value) { std::cout << value << "\n"; };
    

七、与LeetCode 179的关联

在LeetCode 179中,lambda表达式用于定义自定义排序规则:

sort(strs.begin(), strs.end(), [](const string& a, const string& b) {return a + b > b + a;  // 比较拼接后的字符串大小
});

这里:

  • 捕获列表为空:不需要访问外部变量。
  • 参数为两个字符串:表示待比较的数字的字符串形式。
  • 返回布尔值:决定排序顺序。

总结

C++的lambda表达式是一种灵活、高效的创建匿名函数的方式,特别适合在需要临时函数对象的场景中使用。掌握其语法和捕获机制,可以编写出更简洁、更具表现力的代码。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词