@@ -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