@@ -421,7 +421,7 @@ <h2 id="index-_1">前言</h2>
421421<blockquote>
422422<p><img src="../img/bulb.png" height="30px" width="auto" style="margin: 0; border: none"/> 本书还在持续更新中……要追番的话,可以在 <a href="https://github.com/parallel101/cppguidebook">GitHub</a> 点一下右上角的 “Watch” 按钮,每当小彭老师提交新 commit,GitHub 会向你发送一封电子邮件,提醒你小彭老师更新了。</p>
423423</blockquote>
424- <p>更新时间:2025年01月02日 15:39:09 (UTC+08:00)</p>
424+ <p>更新时间:2025年01月05日 10:51:26 (UTC+08:00)</p>
425425<p><a href="https://parallel101.github.io/cppguidebook">在 GitHub Pages 浏览本书</a> | <a href="https://142857.red/book">在小彭老师自己维护的镜像上浏览本书</a></p>
426426<h2 id="index-_2">格式约定</h2>
427427<blockquote>
@@ -1504,7 +1504,8 @@ <h2 id="symbols-linkage">符号的链接类型 (linkage)</h2>
15041504<li><a href="#cpp_tricks-_7">继承构造函数</a></li>
15051505<li><a href="#cpp_tricks-_8">提前返回</a></li>
15061506<li><a href="#cpp_tricks-lambda">立即调用的 Lambda</a></li>
1507- <li><a href="#cpp_tricks-lambda_1">Lambda 复用代码</a></li>
1507+ <li><a href="#cpp_tricks-lambda_1">立即调用的 Lambda 初始化变量</a></li>
1508+ <li><a href="#cpp_tricks-lambda_2">Lambda 复用代码</a></li>
15081509<li><a href="#cpp_tricks-if-else">打表法代替 if-else</a></li>
15091510<li><a href="#cpp_tricks-inline">类内静态成员 inline</a></li>
15101511<li><a href="#cpp_tricks-make_pair">别再 make_pair 啦!</a></li>
@@ -1913,7 +1914,60 @@ <h2 id="cpp_tricks-lambda">立即调用的 Lambda</h2>
19131914}
19141915</code></pre>
19151916<p>这样,return 最多只能打断到当前 Lambda 函数结束的位置,而不能打断整个大函数了。</p>
1916- <h2 id="cpp_tricks-lambda_1">Lambda 复用代码</h2>
1917+ <h2 id="cpp_tricks-lambda_1">立即调用的 Lambda 初始化变量</h2>
1918+ <p>有些变量的初始化,需要大量的准备工作。</p>
1919+ <p>例如创建一个 2048 大小的随机数组,里面填满 0 到 7 的随机整数。</p>
1920+ <pre><code class="language-cpp">std::vector<int> v(2048);
1921+ std::mt19937 gen;
1922+ std::uniform_int_distribution<int> dis(0, 7);
1923+ std::generate(v.begin(), v.end(), [&] {
1924+ return dis(gen);
1925+ });
1926+ </code></pre>
1927+ <p>然而为了产生随机数,我们需要定义大量的临时变量,和函数调用。</p>
1928+ <p>如果有很多个这样初始化工序复杂的变量,每个用到的局部变量名字就会互相冲突,导致无法编译。</p>
1929+ <p>例如我们还想要随机一个 <code>float</code> 类型的数组 <code>v2</code>,其随机值是 0 到 1 的浮点数。</p>
1930+ <p>为了不报错,必须把 <code>v2</code> 使用的所有中间变量都从 <code>dis</code> 改名为 <code>dis2</code>,非常麻烦。</p>
1931+ <p>最重要的是很不直观,你永远不知道某个变量是属于哪个变量的初始化,全部平摊在一个作用域里,影响可读性。</p>
1932+ <pre><code class="language-cpp">std::vector<int> v1(2048);
1933+ std::mt19937 gen1;
1934+ std::uniform_int_distribution<int> dis1(0, 7);
1935+ std::generate(v1.begin(), v1.end(), [&] {
1936+ return dis1(gen1);
1937+ });
1938+
1939+ std::vector<float> v2(2048);
1940+ std::mt19937 gen2;
1941+ std::uniform_real_distribution<float> dis2(0, 1);
1942+ std::generate(v2.begin(), v2.end(), [&] {
1943+ return dis2(gen2);
1944+ });
1945+ </code></pre>
1946+ <p>这时,可以用 Lambda 创建一个作用域,然后用返回的形式初始化变量。</p>
1947+ <pre><code class="language-cpp">std::vector<int> v = [] {
1948+ std::vector<int> v(2048);
1949+ std::mt19937 gen;
1950+ std::uniform_int_distribution<int> dis(0, 7);
1951+ std::generate(v.begin(), v.end(), [&] {
1952+ return dis(gen);
1953+ });
1954+ return v;
1955+ }();
1956+
1957+ std::vector<float> v = [] {
1958+ std::vector<float> v(2048);
1959+ std::mt19937 gen;
1960+ std::uniform_int_distribution<float> dis(0, 1);
1961+ std::generate(v.begin(), v.end(), [&] {
1962+ return dis(gen);
1963+ });
1964+ return v;
1965+ }();
1966+ </code></pre>
1967+ <p>每个 Lambda 内都有自己独立的变量作用域,不会互相干扰。</p>
1968+ <p>所有只在初始化 <code>v1</code> <code>v2</code> 用到的临时变量,即使名字重复也不会打架。</p>
1969+ <p>而且能通过 Lambda 的范围和缩进,明确分辨谁属于谁。</p>
1970+ <h2 id="cpp_tricks-lambda_2">Lambda 复用代码</h2>
19171971<pre><code class="language-cpp">void calc_average() {
19181972 int res = 0;
19191973 int count = 0;
0 commit comments