lambda表达式必须包含[ ]、( )、{ }三部分,缺一不可;捕获列表[ ]不可省略(即使为空),参数括号( )不可替换为{ },函数体{ }不可缺失。

lambda 表达式怎么写才不报错 [ ] ( ) { } 缺一不可
漏掉任意一部分,编译器直接拒绝,不是警告。最常见的是忘记写捕获列表 [ ],哪怕什么都不捕获也得留空;或者把参数括号 ( ) 写成 { },和函数体混淆。
基本结构就是:[capture](parameters) -> return_type { body },其中 -> return_type 可省略(编译器能推导时),但 [ ]、( )、{ } 三者必须存在。
- 没写
[ ]:报错类似error: expected unqualified-id before '[' token - 参数列表为空也要写
(),不能省成[]{}(这是合法的,但表示无参 lambda;而[]{};是定义+调用,[]{};单独一行是表达式语句,不是变量声明) - 想在 lambda 里改外部变量?得显式捕获:
[x](值拷贝)、[&x](引用)、[=]或[&]要谨慎——后者可能悬垂引用
std::sort 里传 lambda,为什么老是编译不过
因为 std::sort 要求比较函数必须接受两个 const 引用或相同类型的值,并返回 bool;lambda 参数类型必须严格匹配容器元素类型,不能靠隐式转换“蒙混过关”。
比如对 vector<int> 排序,写 [](int a, int b) { return a > b; } 没问题;但对 vector<string>,写 [](string a, string b) 就可能低效(多一次拷贝),而写 [](const string& a, const string& b) 更稳妥。
立即学习“C++免费学习笔记(深入)”;
- 参数类型不匹配:比如容器是
vector<const char*>,却传[](char* a, char* b)→ 类型不兼容 - 返回类型非
bool:写成return a - b;(返回int)→ 报错invalid operands to binary expression - 捕获了局部变量但没声明为
mutable,又在函数体内修改它 → 编译失败,除非加mutable关键字
lambda 能不能存到 std::function 里,有啥代价
能存,但别滥用。std::function 是类型擦除容器,每次调用都有间接跳转开销,小函数(比如只做比较或简单计算)直接传 lambda 更快。
典型场景是需要“保存回调”或“运行时决定行为”,比如事件系统、策略配置。这时用 std::function<void(int)> 接收不同 lambda 是合理选择。
- 捕获了局部变量的 lambda 无法赋给函数指针(如
void(*)(int)),只能进std::function - 空捕获列表的 lambda(
[ ](int x){...})可以隐式转成函数指针,零开销;一旦捕获,就必须用std::function -
std::function对象大小通常是 16~32 字节(取决于实现),比裸 lambda(常为 1~8 字节)大得多,频繁拷贝要注意
在类成员函数里用 lambda,this 捕获容易出什么问题
写 [this] 是最常用也最容易翻车的操作:如果 lambda 生命周期超过当前对象,this 就成悬垂指针。尤其在异步、线程、信号槽等场景下,几乎必崩。
更安全的做法是按需捕获具体成员,或用 [weak_this = weak_from_this()](C++17 起,要求类继承 std::enable_shared_from_this)。
- 直接写
[this]() { member_var++; }→ 如果对象已被析构,访问member_var就是未定义行为 -
[=]看似方便,但会把this当指针值拷贝进来,本质还是[this],没解决问题 - 想延长对象生命周期?得确保外层持有
shared_ptr,并在 lambda 里用shared_from_this()或捕获shared_ptr<T>实例
lambda 的语法糖很薄,底下全是对象和调用约定。真正难的从来不是怎么写,而是想清楚“谁拥有数据”“谁控制生命周期”“谁负责销毁”。这些地方一模糊,调试时连栈都对不上。










