@@ -482,6 +482,77 @@ void find(const vector<int> &v, int target) {
482
482
483
483
这样,return 最多只能打断到当前 Lambda 函数结束的位置,而不能打断整个大函数了。
484
484
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
+
485
556
## Lambda 复用代码
486
557
487
558
``` cpp
0 commit comments