C++怎么使用lambda表达式_C++新特性教程【简洁】

6次阅读

Lambda表达式必须包含捕获子句、参数列表和函数体三部分,缺一不可;常见错误包括遗漏[]、参数类型不匹配、引用捕获生命周期不当等。

C++怎么使用lambda表达式_C++新特性教程【简洁】

lambda表达式写法不对,编译直接报错

常见错误是漏掉捕获子句或参数列表,比如写成 [] { return 42; } 是合法的,但写成 { return 42; }(缺[])就会触发类似 Error: expected unqualified-id before '{' Token 的编译错误。

正确结构必须包含三部分:捕获子句([])、参数列表((),可空)、函数体({})。返回类型通常自动推导,除非需要显式指定(用尾置返回类型 -> int)。

  • 捕获为空:用 [];捕获外部变量 a 按值:用 [a];按引用:[&a]
  • 参数列表为空时不能省略括号,必须写 []() { ... }
  • 如果 lambda 要修改按值捕获的变量,得加 mutable,例如 [x]() mutable { x++; }

std::sort 里传 lambda,为什么老出错

最常踩的坑是 lambda 参数类型和容器元素类型不匹配,或者没写 const & 导致不必要的拷贝甚至编译失败。比如对 std::vector<:String></:string> 排序时,写 [](std::string a, std::string b) { ... } 就会频繁构造临时对象;而写成 [](const std::string& a, const std::string& b) { ... } 才合理。

  • std::sort 要求比较函数接受两个参数、返回 bool,且满足严格弱序(不能对相等元素返回 true
  • 捕获外部变量要小心生命周期:如果 lambda 存储到容器里(如 std::function),而捕获的是局部变量的引用,运行时可能访问野指针
  • 简单排序建议直接用 [](auto& a, auto& b) { return a ,c++14 起支持泛型 lambda

lambda 能不能存起来反复用

能,但要看怎么存。直接赋给 auto 最安全,比如 auto f = [](int x) { return x * 2; };;但如果想存进容器或传参,就得用 std::function,它带运行时开销,而且要求类型擦除后仍匹配签名。

立即学习C++免费学习笔记(深入)”;

  • std::function<int> f = [](int x) { return x + 1; };</int> 合法;但 [](double x) { ... } 就不能赋给这个 std::function
  • lambda 本身是唯一类型,不同 lambda 即使长得一样,类型也不同,所以不能直接用 == 比较
  • 若只在局部短生命周期使用,优先用 auto;需类型擦除或动态分发时才上 std::function

捕获 this 时容易悬空或循环引用

在类成员函数里写 [this]() { ... } 很常见,但若这个 lambda 被异步保存(比如塞进线程池、信号槽、定时器),而对象已经析构,调用时就崩。更隐蔽的是用 [=] 捕获 this,表面看是值捕获,其实仍是捕获指针——不是复制对象。

  • 安全做法:需要延长生命周期时,改用 [weak_this = weak_from_this()]() { if (auto p = weak_this.lock()) { ... } }
  • 避免在 lambda 里直接捕获 this 后又把 lambda 存进类成员变量,极易造成循环引用(尤其配合 std::shared_ptr
  • 如果只是同步调用(比如传给 for_each),[this] 没问题;风险全在“跨作用域持有”场景

lambda 看似简单,真正难的是搞清捕获语义和生命周期边界——尤其是当它离开定义它的那几行代码之后。

text=ZqhQzanResources