Skip to content

Commit cc15160

Browse files
committed
deploy: 010d6f3
1 parent a9fc30e commit cc15160

File tree

5 files changed

+96
-28
lines changed

5 files changed

+96
-28
lines changed

Diff for: auto/index.html

+47-13
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@
256256
<ul class="nav flex-column">
257257
</ul>
258258
</li>
259-
<li class="nav-item" data-bs-level="2"><a href="#auto_4" class="nav-link">auto 推导为引用</a>
259+
<li class="nav-item" data-bs-level="2"><a href="#auto_5" class="nav-link">auto 推导为引用</a>
260260
<ul class="nav flex-column">
261261
</ul>
262262
</li>
@@ -279,31 +279,31 @@ <h2 id="auto_2">返回类型 <code>auto</code></h2>
279279
<p><img src="../img/awesomeface.png" height="30px" width="auto" style="margin: 0; border: none"/> 闹了半天,还是要写返回类型,就只是挪到后面去好看一点……</p>
280280
<p><img src="../img/question.png" height="30px" width="auto" style="margin: 0; border: none"/> 当初引入后置返回类型实际的用途是 <code>auto f(int x) -&gt; decltype(x * x) { return x * x; }</code> 这种情况,但很容易被接下来 C++14 引入的真正 <code>auto</code> 返回类型推导平替了。</p>
281281
</blockquote>
282-
<p>C++14 引入了函数<strong>返回类型推导</strong><code>auto</code> 才算真正意义上能用做函数返回类型,它会自动根据函数中的 <code>return</code> 表达式推导出函数的返回类型。</p>
282+
<p>但是 C++14 引入了函数<strong>返回类型推导</strong><code>auto</code> 才算真正意义上能用做函数返回类型,它会自动根据函数中的 <code>return</code> 表达式推导出函数的返回类型。</p>
283283
<pre><code class="language-cpp">auto f(int x) {
284-
return x * x; // 表达式 `x * x` 的类型为 int,所以 auto 类型推导为 int
284+
return x * x; // 表达式 `x * x` 的类型为 int,所以 auto 类型推导为 int
285285
}
286286
// 等价于:
287287
int f() {
288-
return x * x;
288+
return x * x;
289289
}
290290
</code></pre>
291291
<p>如果函数中没有 <code>return</code> 语句,那么 <code>auto</code> 会被自动推导为 <code>void</code>,非常方便。</p>
292292
<pre><code class="language-cpp">auto f() {
293-
std::println(&quot;hello&quot;);
293+
std::println(&quot;hello&quot;);
294294
}
295295
// 等价于:
296296
void f() {
297-
std::println(&quot;hello&quot;);
297+
std::println(&quot;hello&quot;);
298298
}
299299
</code></pre>
300300
<p>值得注意的是,返回类型用 <code>auto</code> 来推导的函数,如果有多条 <code>return</code> 语句,那么他们必须都返回相同的类型,否则报错。</p>
301301
<pre><code class="language-cpp">auto f(int x) {
302-
if (x &gt; 0) {
303-
return 1; // int
304-
} else {
305-
return 3.14; // double
306-
}
302+
if (x &gt; 0) {
303+
return 1; // int
304+
} else {
305+
return 3.14; // double
306+
}
307307
} // 错误:有歧义,无法确定 auto 应该推导为 int 还是 double
308308
</code></pre>
309309
<p><code>auto</code> 还有一个缺点是,无法用于“分离声明和定义”的情况。因为推导 <code>auto</code> 类型需要知道函数体,才能看到里面的 <code>return</code> 表达式是什么类型。所以当 <code>auto</code> 返回类型被用于函数的非定义声明时,会直接报错。</p>
@@ -316,7 +316,41 @@ <h2 id="auto_2">返回类型 <code>auto</code></h2>
316316
<p>因此,<code>auto</code> 通常只适用于头文件中“就地定义”的 <code>inline</code> 函数,不适合需要“分离 .cpp 文件”的函数。</p>
317317
<h2 id="auto_3">参数类型 <code>auto</code></h2>
318318
<p>C++20 引入了<strong>模板参数推导</strong>,可以让我们在函数参数中也使用 <code>auto</code></p>
319-
<p>TODO: 介绍</p>
319+
<p>在函数参数中也使用 <code>auto</code> 实际上等价于将该参数声明为模板参数,仅仅是一种更便捷的写法。</p>
320+
<pre><code class="language-cpp">void func(auto x) {
321+
std::cout &lt;&lt; x;
322+
}
323+
// 等价于:
324+
template &lt;typename T&gt;
325+
void func(T x) {
326+
std::cout &lt;&lt; x;
327+
}
328+
329+
func(1); // 自动推导为调用 func&lt;int&gt;(1)
330+
func(3.14); // 自动推导为调用 func&lt;double&gt;(3.14)
331+
</code></pre>
332+
<p>如果参数类型的 <code>auto</code> 带有如 <code>auto &amp;</code> 这样的修饰,则实际上等价于相应模板函数的 <code>T &amp;</code></p>
333+
<pre><code class="language-cpp">// 自动推导为常引用
334+
void func(auto const &amp;x) {
335+
std::cout &lt;&lt; x;
336+
}
337+
// 等价于:
338+
template &lt;typename T&gt;
339+
void func(T const &amp;x) {
340+
std::cout &lt;&lt; x;
341+
}
342+
343+
// 自动推导为万能引用
344+
void func(auto &amp;&amp;x) {
345+
std::cout &lt;&lt; x;
346+
}
347+
// 等价于:
348+
template &lt;typename T&gt;
349+
void func(T &amp;&amp;x) {
350+
std::cout &lt;&lt; x;
351+
}
352+
</code></pre>
353+
<h3 id="auto_4"><code>auto</code> 在多态中的妙用</h3>
320354
<p>传统的,基于类型重载的:</p>
321355
<pre><code class="language-cpp">int square(int x) {
322356
return x * x;
@@ -343,7 +377,7 @@ <h2 id="auto_3">参数类型 <code>auto</code></h2>
343377
// 即使未来产生了 float 版的需求,也不用添加任何代码,因为是 square 是很方便的模板函数
344378
}
345379
</code></pre>
346-
<h2 id="auto_4"><code>auto</code> 推导为引用</h2>
380+
<h2 id="auto_5"><code>auto</code> 推导为引用</h2>
347381
<p>TODO: 继续介绍 <code>auto</code>, <code>auto const</code>, <code>auto &amp;</code>, <code>auto const &amp;</code>, <code>auto &amp;&amp;</code>, <code>decltype(auto)</code>, <code>auto *</code>, <code>auto const *</code></p></div>
348382
</div>
349383
</div>

Diff for: index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ <h2 id="_1">前言</h2>
292292
<blockquote>
293293
<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>
294294
</blockquote>
295-
<p>更新时间:2024年11月01日 12:54:16 (UTC+08:00)</p>
295+
<p>更新时间:2024年11月09日 11:37:54 (UTC+08:00)</p>
296296
<p><a href="https://parallel101.github.io/cppguidebook">在 GitHub Pages 浏览本书</a> | <a href="https://142857.red/book">在小彭老师自己维护的镜像上浏览本书</a></p>
297297
<h2 id="_2">格式约定</h2>
298298
<blockquote>

Diff for: print_page/index.html

+47-13
Original file line numberDiff line numberDiff line change
@@ -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>更新时间:2024年11月01日 12:54:16 (UTC+08:00)</p>
424+
<p>更新时间:2024年11月09日 11:37:54 (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>
@@ -941,31 +941,31 @@ <h2 id="auto-auto_2">返回类型 <code>auto</code></h2>
941941
<p><img src="../img/awesomeface.png" height="30px" width="auto" style="margin: 0; border: none"/> 闹了半天,还是要写返回类型,就只是挪到后面去好看一点……</p>
942942
<p><img src="../img/question.png" height="30px" width="auto" style="margin: 0; border: none"/> 当初引入后置返回类型实际的用途是 <code>auto f(int x) -&gt; decltype(x * x) { return x * x; }</code> 这种情况,但很容易被接下来 C++14 引入的真正 <code>auto</code> 返回类型推导平替了。</p>
943943
</blockquote>
944-
<p>C++14 引入了函数<strong>返回类型推导</strong>,<code>auto</code> 才算真正意义上能用做函数返回类型,它会自动根据函数中的 <code>return</code> 表达式推导出函数的返回类型。</p>
944+
<p>但是 C++14 引入了函数<strong>返回类型推导</strong>,<code>auto</code> 才算真正意义上能用做函数返回类型,它会自动根据函数中的 <code>return</code> 表达式推导出函数的返回类型。</p>
945945
<pre><code class="language-cpp">auto f(int x) {
946-
return x * x; // 表达式 `x * x` 的类型为 int,所以 auto 类型推导为 int
946+
return x * x; // 表达式 `x * x` 的类型为 int,所以 auto 类型推导为 int
947947
}
948948
// 等价于:
949949
int f() {
950-
return x * x;
950+
return x * x;
951951
}
952952
</code></pre>
953953
<p>如果函数中没有 <code>return</code> 语句,那么 <code>auto</code> 会被自动推导为 <code>void</code>,非常方便。</p>
954954
<pre><code class="language-cpp">auto f() {
955-
std::println(&quot;hello&quot;);
955+
std::println(&quot;hello&quot;);
956956
}
957957
// 等价于:
958958
void f() {
959-
std::println(&quot;hello&quot;);
959+
std::println(&quot;hello&quot;);
960960
}
961961
</code></pre>
962962
<p>值得注意的是,返回类型用 <code>auto</code> 来推导的函数,如果有多条 <code>return</code> 语句,那么他们必须都返回相同的类型,否则报错。</p>
963963
<pre><code class="language-cpp">auto f(int x) {
964-
if (x &gt; 0) {
965-
return 1; // int
966-
} else {
967-
return 3.14; // double
968-
}
964+
if (x &gt; 0) {
965+
return 1; // int
966+
} else {
967+
return 3.14; // double
968+
}
969969
} // 错误:有歧义,无法确定 auto 应该推导为 int 还是 double
970970
</code></pre>
971971
<p><code>auto</code> 还有一个缺点是,无法用于“分离声明和定义”的情况。因为推导 <code>auto</code> 类型需要知道函数体,才能看到里面的 <code>return</code> 表达式是什么类型。所以当 <code>auto</code> 返回类型被用于函数的非定义声明时,会直接报错。</p>
@@ -978,7 +978,41 @@ <h2 id="auto-auto_2">返回类型 <code>auto</code></h2>
978978
<p>因此,<code>auto</code> 通常只适用于头文件中“就地定义”的 <code>inline</code> 函数,不适合需要“分离 .cpp 文件”的函数。</p>
979979
<h2 id="auto-auto_3">参数类型 <code>auto</code></h2>
980980
<p>C++20 引入了<strong>模板参数推导</strong>,可以让我们在函数参数中也使用 <code>auto</code>。</p>
981-
<p>TODO: 介绍</p>
981+
<p>在函数参数中也使用 <code>auto</code> 实际上等价于将该参数声明为模板参数,仅仅是一种更便捷的写法。</p>
982+
<pre><code class="language-cpp">void func(auto x) {
983+
std::cout &lt;&lt; x;
984+
}
985+
// 等价于:
986+
template &lt;typename T&gt;
987+
void func(T x) {
988+
std::cout &lt;&lt; x;
989+
}
990+
991+
func(1); // 自动推导为调用 func&lt;int&gt;(1)
992+
func(3.14); // 自动推导为调用 func&lt;double&gt;(3.14)
993+
</code></pre>
994+
<p>如果参数类型的 <code>auto</code> 带有如 <code>auto &amp;</code> 这样的修饰,则实际上等价于相应模板函数的 <code>T &amp;</code>。</p>
995+
<pre><code class="language-cpp">// 自动推导为常引用
996+
void func(auto const &amp;x) {
997+
std::cout &lt;&lt; x;
998+
}
999+
// 等价于:
1000+
template &lt;typename T&gt;
1001+
void func(T const &amp;x) {
1002+
std::cout &lt;&lt; x;
1003+
}
1004+
1005+
// 自动推导为万能引用
1006+
void func(auto &amp;&amp;x) {
1007+
std::cout &lt;&lt; x;
1008+
}
1009+
// 等价于:
1010+
template &lt;typename T&gt;
1011+
void func(T &amp;&amp;x) {
1012+
std::cout &lt;&lt; x;
1013+
}
1014+
</code></pre>
1015+
<h3 id="auto-auto_4"><code>auto</code> 在多态中的妙用</h3>
9821016
<p>传统的,基于类型重载的:</p>
9831017
<pre><code class="language-cpp">int square(int x) {
9841018
return x * x;
@@ -1005,7 +1039,7 @@ <h2 id="auto-auto_3">参数类型 <code>auto</code></h2>
10051039
// 即使未来产生了 float 版的需求,也不用添加任何代码,因为是 square 是很方便的模板函数
10061040
}
10071041
</code></pre>
1008-
<h2 id="auto-auto_4"><code>auto</code> 推导为引用</h2>
1042+
<h2 id="auto-auto_5"><code>auto</code> 推导为引用</h2>
10091043
<p>TODO: 继续介绍 <code>auto</code>, <code>auto const</code>, <code>auto &amp;</code>, <code>auto const &amp;</code>, <code>auto &amp;&amp;</code>, <code>decltype(auto)</code>, <code>auto *</code>, <code>auto const *</code></p></section><section class="print-page" id="symbols"><h1 id="symbols-_1">重新认识声明与定义(未完工)</h1>
10101044
<div class="toc">
10111045
<ul>

Diff for: search/search_index.json

+1-1
Large diffs are not rendered by default.

Diff for: sitemap.xml.gz

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)