@@ -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) -> 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// 等价于:
949949int 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("hello");
955+ std::println("hello");
956956}
957957// 等价于:
958958void f() {
959- std::println("hello");
959+ std::println("hello");
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 > 0) {
965- return 1; // int
966- } else {
967- return 3.14; // double
968- }
964+ if (x > 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 << x;
984+ }
985+ // 等价于:
986+ template <typename T>
987+ void func(T x) {
988+ std::cout << x;
989+ }
990+
991+ func(1); // 自动推导为调用 func<int>(1)
992+ func(3.14); // 自动推导为调用 func<double>(3.14)
993+ </code></pre>
994+ <p>如果参数类型的 <code>auto</code> 带有如 <code>auto &</code> 这样的修饰,则实际上等价于相应模板函数的 <code>T &</code>。</p>
995+ <pre><code class="language-cpp">// 自动推导为常引用
996+ void func(auto const &x) {
997+ std::cout << x;
998+ }
999+ // 等价于:
1000+ template <typename T>
1001+ void func(T const &x) {
1002+ std::cout << x;
1003+ }
1004+
1005+ // 自动推导为万能引用
1006+ void func(auto &&x) {
1007+ std::cout << x;
1008+ }
1009+ // 等价于:
1010+ template <typename T>
1011+ void func(T &&x) {
1012+ std::cout << 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 &</code>, <code>auto const &</code>, <code>auto &&</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>
0 commit comments