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

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










