Skip to content

Commit 976cc5f

Browse files
committed
lambda tip
1 parent 9e9b297 commit 976cc5f

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

docs/cpp_tricks.md

+71
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,77 @@ void find(const vector<int> &v, int target) {
482482

483483
这样,return 最多只能打断到当前 Lambda 函数结束的位置,而不能打断整个大函数了。
484484

485+
## 立即调用的 Lambda 初始化变量
486+
487+
有些变量的初始化,需要大量的准备工作。
488+
489+
例如创建一个 2048 大小的随机数组,里面填满 0 到 7 的随机整数。
490+
491+
```cpp
492+
std::vector<int> v(2048);
493+
std::mt19937 gen;
494+
std::uniform_int_distribution<int> dis(0, 7);
495+
std::generate(v.begin(), v.end(), [&] {
496+
return dis(gen);
497+
});
498+
```
499+
500+
然而为了产生随机数,我们需要定义大量的临时变量,和函数调用。
501+
502+
如果有很多个这样初始化工序复杂的变量,每个用到的局部变量名字就会互相冲突,导致无法编译。
503+
504+
例如我们还想要随机一个 `float` 类型的数组 `v2`,其随机值是 0 到 1 的浮点数。
505+
506+
为了不报错,必须把 `v2` 使用的所有中间变量都从 `dis` 改名为 `dis2`,非常麻烦。
507+
508+
最重要的是很不直观,你永远不知道某个变量是属于哪个变量的初始化,全部平摊在一个作用域里,影响可读性。
509+
510+
```cpp
511+
std::vector<int> v1(2048);
512+
std::mt19937 gen1;
513+
std::uniform_int_distribution<int> dis1(0, 7);
514+
std::generate(v1.begin(), v1.end(), [&] {
515+
return dis1(gen1);
516+
});
517+
518+
std::vector<float> v2(2048);
519+
std::mt19937 gen2;
520+
std::uniform_real_distribution<float> dis2(0, 1);
521+
std::generate(v2.begin(), v2.end(), [&] {
522+
return dis2(gen2);
523+
});
524+
```
525+
526+
这时,可以用 Lambda 创建一个作用域,然后用返回的形式初始化变量。
527+
528+
```cpp
529+
std::vector<int> v = [] {
530+
std::vector<int> v(2048);
531+
std::mt19937 gen;
532+
std::uniform_int_distribution<int> dis(0, 7);
533+
std::generate(v.begin(), v.end(), [&] {
534+
return dis(gen);
535+
});
536+
return v;
537+
}();
538+
539+
std::vector<float> v = [] {
540+
std::vector<float> v(2048);
541+
std::mt19937 gen;
542+
std::uniform_int_distribution<float> dis(0, 1);
543+
std::generate(v.begin(), v.end(), [&] {
544+
return dis(gen);
545+
});
546+
return v;
547+
}();
548+
```
549+
550+
每个 Lambda 内都有自己独立的变量作用域,不会互相干扰。
551+
552+
所有只在初始化 `v1` `v2` 用到的临时变量,即使名字重复也不会打架。
553+
554+
而且能通过 Lambda 的范围和缩进,明确分辨谁属于谁。
555+
485556
## Lambda 复用代码
486557

487558
```cpp

0 commit comments

Comments
 (0)