Effective Modern C++ 第六章 lambda 表达式
lambda 能做到的,手写也能做到,但是 lambda 实在是太方便了,以至于对 C++ 开发产生了颠覆性的影响:
常用场景
- STL _if 算法族的谓词
- 智能指针的自定义析构器
- 线程 API 的条件变量(对谓词进行特化处理)
- 临时制作回调函数、接口适配函数
条款 31:避免默认捕获
- lambda 捕获只能捕获创建 lambda 作用域内可见的局部、非静态变量(包括形参)
- 每个非静态成员函数都持有 this 指针,成员函数中访问成员变量都是通过 this 指针
- 成员函数中,无法捕获成员变量,成员函数中,实际上捕获的是 this 指针!
- 【最佳实践】新建一个成员变量的副本,然后显式、值捕获该副本
- 不能捕获静态变量!
- 使用 lambda 时,要确保引用捕获的对象仍然有效!
- 按值捕获的 this 指针也要保证使用 lambda 时,指针仍然有效!
无法局部静态变量的测试代码:
vector<function<void(void)>> callables;
void lambdaAddTest() {
static int si = 0;
// callables.emplace_back([si] { cout << si; }); // error: 'si' cannot be captured because it does not have automatic storage duration
callables.emplace_back([=] { cout << si; }); // 警告:此处没有捕获任何变量!
++si;
}
int main() {
lambdaAddTest();
for (const auto& l : callables) {l();}
lambdaAddTest();
for (const auto& l : callables) {l();}
lambdaAddTest();
for (const auto& l : callables) {l();}
}
运行结果
122333
条款 32:使用【初始化捕获】将对象移入闭包
auto p = make_unique<Foo>();
... // 操作 p
auto func1 = [lp = move(p)] { /* 使用 lp */ };
auto func2 = [lp = make_unique<Bar>()] { /* 使用 lp */ };
本文作者:Zijian/TENG(微信公众号:好记性如烂笔头),转载请注明原文链接:https://www.cnblogs.com/tengzijian/p/17093023.html