<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[C++11: 核心语言特性0: 类型自动推导 - auto和decltype]]></title><description><![CDATA[<p dir="auto">auto 和 decltype 是C++11引入的强有力的<strong>类型自动推导</strong>工具. 不仅让代码变的更加简洁, 还增强了模板和泛型的表达能力</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Book</th>
<th>Video</th>
<th>Code</th>
<th>X</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="https://en.cppreference.com/w/cpp/language/auto" rel="nofollow ugc">cppreference-auto</a> / <a href="https://en.cppreference.com/w/cpp/language/decltype" rel="nofollow ugc">cppreference-decltype</a> / <a href="https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md" rel="nofollow ugc">markdown</a></td>
<td><a href="https://www.bilibili.com/video/BV1xkdYYUEyH" rel="nofollow ugc">视频解读</a></td>
<td><a href="https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/00-auto-and-decltype-0.cpp" rel="nofollow ugc">练习代码</a></td>
<td></td>
</tr>
</tbody>
</table>
<p dir="auto"><img src="/assets/uploads/files/1751953985777-16x9-resized.png" alt="16x9.png" class=" img-fluid img-markdown" /></p>
<p dir="auto"><strong>为什么引入?</strong></p>
<ul>
<li>解决类型声明过于复杂的问题</li>
<li>模板应用中, 获取对象或表达式类型的需求</li>
<li>为lambda表达式的定义做支撑</li>
</ul>
<p dir="auto"><strong>auto和decltype有什么区别?</strong></p>
<ul>
<li>auto常常用于变量定义, 推导的类型可能丢失const或引用(可显示指定进行保留auto &amp;)</li>
<li>decltype获取表达式的<strong>精确类型</strong></li>
<li>auto通常无法作为模板类型参数使用</li>
</ul>
<h2>一、基础用法和场景</h2>
<h3>声明定义</h3>
<blockquote>
<p dir="auto">充当类型站位符, 辅助变量的定义或声明。使用auto时变量必须要初始化, decltype可以不用初始化</p>
</blockquote>
<pre><code class="language-cpp">int b = 2;
auto b1 = b;
decltype(b) b2 = b;
decltype(b) b3; // 可以不用初始化
</code></pre>
<h3>表达式类型推导</h3>
<blockquote>
<p dir="auto">常常用于复杂表达式的类型推导, 确保计算精度</p>
</blockquote>
<pre><code class="language-c++">int a = 1;

auto b1 = a + 2;
decltype(a + 2 + 1.1) b2 = a + 2 + 1.1;

auto c1 = a + '0';
decltype(2 + 'a') c2 = 2 + 'a';
</code></pre>
<h3>复杂类型推导</h3>
<p dir="auto"><strong>迭代器类型推导</strong></p>
<pre><code class="language-c++">std::vector&lt;int&gt; v = {1, 2, 3};

auto it = v.begin(); // 自动推导it类型
// decltype(v.begin()) it = v.begin();
for (; it != v.end(); ++it) {
    std::cout &lt;&lt; *it &lt;&lt; " ";
}
</code></pre>
<p dir="auto"><strong>函数类型推导</strong></p>
<blockquote>
<p dir="auto">对于函数或lambda表达式这种复杂类型, 常常使用auto和decltype. 一般, lambda定义用auto,  模板类型参数用decltype</p>
</blockquote>
<pre><code class="language-c++">int add_func(int a, int b) {
    return a + b;
}

int main() {
    auto minus_func = [](int a, int b) { return a - b; };

    std::vector&lt;std::function&lt;decltype(add_func)&gt;&gt; funcVec = {
        add_func,
        minus_func
    };

    funcVec[0](1, 2);
    funcVec[1](1, 2);
    //...
}
</code></pre>
<h3>函数返回值类型推导</h3>
<p dir="auto"><strong>语法糖用法</strong></p>
<blockquote>
<p dir="auto">auto为后置返回类型函数定义写法做支持, 并可以配合decltype进行返回类型推导使用</p>
</blockquote>
<pre><code class="language-cpp">auto main() -&gt; int {
    return 0;
}

auto add(int a, double b) -&gt; decltype(a + b) {
    return a + b;
}
</code></pre>
<p dir="auto"><strong>函数模板返回值类型推导</strong></p>
<blockquote>
<p dir="auto">当无法确定模板返回值时可以用auto + decltype做推导, 可以让add支持一般类型int, double,... 和 复杂类型 Point, Vec,... 增强泛型的表达能力. (c++14中可以省略decltype)</p>
</blockquote>
<pre><code class="language-cpp">template&lt;typename T1, typename T2&gt;
auto add(T1 a, T2 b) -&gt; decltype(a + b) {
    return a + b;
}
</code></pre>
<h3>类/结构体成员类型推导</h3>
<pre><code class="language-cpp">struct Object {
    const int a;
    double b;
    Object() : a(1), b(2.0) { }
};

int main() {
    const Object obj;

    auto a = obj.a;
    std::vector&lt;decltype(obj.b)&gt; vec;
}
</code></pre>
<h2>二、注意事项 - 括号带来的影响</h2>
<h3>decltype(obj) 和 decltype( (obj) )的区别</h3>
<ul>
<li>一般<code>decltype(obj)</code>获取的时其声明类型</li>
<li>而<code>decltype( (obj) )</code> 获取的是 <code>(obj)</code> 这个表达式的类型(左值表达式)</li>
</ul>
<pre><code class="language-cpp">int a = 1;
decltype(a) b; // 推导结果为a的声明类型int 
decltype( (a) ) c; // 推导结果为(a)这个左值表达式的类型 int &amp; 
</code></pre>
<h3>decltype(obj.b) 和 decltype( (obj.b) )的区别</h3>
<ul>
<li><code>decltype( (obj.b) )</code>: 从表达式视角做类型推导, obj定义类型会影响推导结果. 例如, 如果obj被const修饰时, const会限定obj.b的访问为const</li>
<li><code>decltype(obj.b)</code>: 由于推导的是成员声明类型, 所以不会受obj定义的影响</li>
</ul>
<pre><code class="language-cpp">struct Object {
    const int a;
    double b;
    Object() : a(1), b(2.0) { }
};

int main() {
    Object obj;
    const Object obj1;

    decltype(obj.b)  // double
    decltype(obj1.b) // double

    decltype( (obj.b) ) // double &amp; 
    decltype( (obj1.b) ) // 受obj1定义的const修饰影响, 所以是 const double &amp;
}
</code></pre>
<h3>右值引用变量, 在表达式中是左值</h3>
<pre><code class="language-cpp">int &amp;&amp;b = 1;

decltype(b) // 推导结果是声明类型 int &amp;&amp;
decltype( (b) ) // 推导结果是 int &amp;
</code></pre>
<h2>三、其他</h2>
<ul>
<li><a href="https://forum.d2learn.org/category/20" rel="nofollow ugc">交流讨论</a></li>
<li><a href="https://github.com/Sunrisepeak/mcpp-standard" rel="nofollow ugc">mcpp-standard教程仓库</a></li>
<li><a href="https://space.bilibili.com/65858958/lists/5208246" rel="nofollow ugc">教程视频列表</a></li>
<li><a href="https://github.com/d2learn/xlings" rel="nofollow ugc">教程支持工具-xlings</a></li>
</ul>
]]></description><link>http://forum.d2learn.org/topic/82/c-11-核心语言特性0-类型自动推导-auto和decltype</link><generator>RSS for Node</generator><lastBuildDate>Thu, 13 Aug 2026 16:07:37 GMT</lastBuildDate><atom:link href="http://forum.d2learn.org/topic/82.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 13 Apr 2025 07:02:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to C++11: 核心语言特性0: 类型自动推导 - auto和decltype on Sun, 13 Apr 2025 07:04:22 GMT]]></title><description><![CDATA[<p dir="auto"><a href="https://en.cppreference.com/w/cpp/language/decltype" rel="nofollow ugc">https://en.cppreference.com/w/cpp/language/decltype</a></p>
<p dir="auto"><img src="/assets/uploads/files/1744527858672-125fede7-3314-4faf-ae1b-07cad6522c5e-image.png" alt="image.png" class=" img-fluid img-markdown" /></p>
]]></description><link>http://forum.d2learn.org/post/358</link><guid isPermaLink="true">http://forum.d2learn.org/post/358</guid><dc:creator><![CDATA[SPeak]]></dc:creator><pubDate>Sun, 13 Apr 2025 07:04:22 GMT</pubDate></item></channel></rss>