318 lines
33 KiB
HTML
318 lines
33 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>基于范围的 for 循环 (C++11 起)</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-cpp_language_range-for skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">基于范围的 for 循环 <span class="t-mark-rev t-since-cxx11">(C++11 起)</span></h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>在一个范围上执行 <code>for</code> 循环。</p>
|
|
<p>用作对范围中的各个值(如容器中的所有元素)进行操作的传统 <a href="cpp-language-for.html">for 循环</a>的更加可读的等价版本。</p>
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><span class="t-spar">属性</span><span class="t-mark">(可选)</span> <code><b>for (</b></code> <span class="t-spar">初始化语句</span><span class="t-mark">(可选)</span><span class="t-spar">范围变量声明</span> <code><b>:</b></code> <span class="t-spar">范围表达式</span> <code><b>)</b></code> <span class="t-spar">循环语句</span></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">属性</span></td>
|
|
<td>-</td>
|
|
<td>任意数量的<a href="cpp-language-attributes.html">属性</a></td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">初始化语句</span></td>
|
|
<td>-</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span> 以下之一:
|
|
<ul>
|
|
<li><a href="cpp-language-statements.html">表达式语句</a>(可以是<i>空语句</i>“<code><b>;</b></code>”)</li>
|
|
<li><a href="cpp-language-declarations.html">简单声明</a>,典型地为带初始化器的变量声明,但它可以声明任意多个变量,或者是<a href="cpp-language-structured_binding.html">结构化绑定声明</a></li>
|
|
</ul>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx23">
|
|
<td>
|
|
<ul>
|
|
<li><a href="cpp-language-type_alias.html">别名声明</a></li>
|
|
</ul>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<dl>
|
|
<dd>注意,所有 <span class="t-spar">初始化语句</span> 必然以分号 <code><b>;</b></code> 结尾,因此它经常被非正式地描述为后随分号的表达式或声明。</dd>
|
|
</dl>
|
|
</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">范围变量声明</span></td>
|
|
<td>-</td>
|
|
<td>一个具名变量的<a href="cpp-language-declarations.html">声明</a>,它的类型是由 <span class="t-spar">范围表达式</span> 所表示的序列的元素的类型,或该类型的引用。通常用 <a href="cpp-language-auto.html">auto 说明符</a>进行自动类型推导。</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">范围表达式</span></td>
|
|
<td>-</td>
|
|
<td>可以表示一个合适的序列(数组,或定义了 <code>begin</code> 和 <code>end</code> 成员函数或自由函数的对象,见下文)的任意<a href="cpp-language-expressions.html">表达式</a>,或一个<a href="cpp-language-list_initialization.html">花括号初始化器列表</a>。</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">循环语句</span></td>
|
|
<td>-</td>
|
|
<td>任意<a href="cpp-language-statements.html">语句</a>,通常是一条复合语句,它是循环体</td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p><span class="t-spar">范围变量声明</span> 可以是<a href="cpp-language-structured_binding.html">结构化绑定声明</a>:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">for</span> <span class="br0">(</span><span class="kw4">auto</span><span class="sy3">&&</span> <span class="br0">[</span>first,second<span class="br0">]</span> <span class="sy4">:</span> mymap<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="co1">// 使用 first 和 second</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>上述语法产生的代码等价于下列代码(<b><code>__range</code></b>、<b><code>__begin</code></b> 和 <b><code>__end</code></b> 仅用于阐释):</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx17">
|
|
<td>
|
|
<p><code><b>{</b></code><br /></p>
|
|
<dl>
|
|
<dd><code><b>auto && __range =</b></code> <span class="t-spar">范围表达式</span> <code><b>;</b></code><br /></dd>
|
|
<dd><code><b>for (auto __begin =</b></code> <i>首表达式</i><code><b>,</b></code> <code><b>__end =</b></code> <i>尾表达式</i> <code><b>; __begin != __end; ++__begin) {</b></code><br />
|
|
<dl>
|
|
<dd><span class="t-spar">范围变量声明</span> <code><b>= *__begin;</b></code><br /></dd>
|
|
<dd><span class="t-spar">循环语句</span><br /></dd>
|
|
</dl>
|
|
</dd>
|
|
<dd><code><b>}</b></code><br /></dd>
|
|
</dl>
|
|
<p><code><b>}</b></code><br /></p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx17 t-until-cxx20">
|
|
<td>
|
|
<p><code><b>{</b></code><br /></p>
|
|
<dl>
|
|
<dd><code><b>auto && __range =</b></code> <span class="t-spar">范围表达式</span> <code><b>;</b></code><br /></dd>
|
|
<dd><code><b>auto __begin =</b></code> <i>首表达式</i> <code><b>;</b></code><br /></dd>
|
|
<dd><code><b>auto __end =</b></code> <i>尾表达式</i> <code><b>;</b></code><br /></dd>
|
|
<dd><code><b>for ( ; __begin != __end; ++__begin) {</b></code><br />
|
|
<dl>
|
|
<dd><span class="t-spar">范围变量声明</span> <code><b>= *__begin;</b></code><br /></dd>
|
|
<dd><span class="t-spar">循环语句</span><br /></dd>
|
|
</dl>
|
|
</dd>
|
|
<dd><code><b>}</b></code><br /></dd>
|
|
</dl>
|
|
<p><code><b>}</b></code><br /></p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span><br />
|
|
<span class="t-mark-rev t-until-cxx20">(C++20 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx20">
|
|
<td>
|
|
<p><code><b>{</b></code><br /></p>
|
|
<dl>
|
|
<dd><span class="t-spar">初始化语句</span><br /></dd>
|
|
<dd><code><b>auto && __range =</b></code> <span class="t-spar">范围表达式</span> <code><b>;</b></code><br /></dd>
|
|
<dd><code><b>auto __begin =</b></code> <i>首表达式</i> <code><b>;</b></code><br /></dd>
|
|
<dd><code><b>auto __end =</b></code> <i>尾表达式</i> <code><b>;</b></code><br /></dd>
|
|
<dd><code><b>for ( ; __begin != __end; ++__begin) {</b></code><br />
|
|
<dl>
|
|
<dd><span class="t-spar">范围变量声明</span> <code><b>= *__begin;</b></code><br /></dd>
|
|
<dd><span class="t-spar">循环语句</span><br /></dd>
|
|
</dl>
|
|
</dd>
|
|
<dd><code><b>}</b></code><br /></dd>
|
|
</dl>
|
|
<p><code><b>}</b></code><br /></p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>要迭代的序列或范围通过对 <span class="t-spar">范围表达式</span> 求值以确定。依次对序列的每个元素进行解引用,并赋值给具有 <span class="t-spar">范围变量声明</span> 中所给定的类型和名字的变量。</p>
|
|
<p><i><code>首表达式</code></i> 和 <i><code>尾表达式</code></i> 定义如下:</p>
|
|
<ul>
|
|
<li>如果 <span class="t-spar">范围表达式</span> 是数组类型的表达式,那么 <i><code>首表达式</code></i> 是 <span class="t-c"><span class="mw-geshi cpp source-cpp">__range</span></span> 而 <i><code>尾表达式</code></i> 是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">(</span>__range <span class="sy2">+</span> __bound<span class="br0">)</span></span></span>,其中 <code>__bound</code> 是数组的元素数目(如果数组大小未知或拥有不完整类型,那么程序非良构)</li>
|
|
<li>如果 <span class="t-spar">范围表达式</span> 是同时拥有名为 <span class="t-c"><span class="mw-geshi cpp source-cpp">begin</span></span> 以及名为 <span class="t-c"><span class="mw-geshi cpp source-cpp">end</span></span> 的成员的类类型 <code>C</code> 的表达式(不管这些成员的类型或可见性),那么 <i><code>首表达式</code></i> 是 <span class="t-c"><span class="mw-geshi cpp source-cpp">__range.<span class="me1">begin</span><span class="br0">(</span><span class="br0">)</span></span></span> 而 <i><code>尾表达式</code></i> 是 <span class="t-c"><span class="mw-geshi cpp source-cpp">__range.<span class="me1">end</span><span class="br0">(</span><span class="br0">)</span></span></span>;</li>
|
|
<li>否则,<i><code>首表达式</code></i> 是 <span class="t-c"><span class="mw-geshi cpp source-cpp">begin<span class="br0">(</span>__range<span class="br0">)</span></span></span> 而 <i><code>尾表达式</code></i> 是 <span class="t-c"><span class="mw-geshi cpp source-cpp">end<span class="br0">(</span>__range<span class="br0">)</span></span></span>,通过<a href="cpp-language-adl.html">实参依赖查找</a>进行查找(不进行非实参依赖查找)。</li>
|
|
</ul>
|
|
<p>正如传统循环一样,<a href="cpp-language-break.html">break 语句</a>可用于提早退出循环,且 <a href="cpp-language-continue.html">continue 语句</a>能用于以下个元素重新开始循环。</p>
|
|
<h3><span class="mw-headline" id=".E4.B8.B4.E6.97.B6.E8.8C.83.E5.9B.B4.E8.A1.A8.E8.BE.BE.E5.BC.8F">临时范围表达式</span></h3>
|
|
<p>如果 <span class="t-spar">范围表达式</span> 返回临时量,那么它的生存期延续到循环结尾,如绑定到转发引用 <b><code>__range</code></b> 所示,但要注意 <span class="t-spar">范围表达式</span> 中任何临时量生存期都<i>不</i>会延长。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">for</span> <span class="br0">(</span><span class="kw4">auto</span><span class="sy3">&</span> x <span class="sy4">:</span> foo<span class="br0">(</span><span class="br0">)</span>.<span class="me1">items</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="coMULTI">/* .. */</span> <span class="br0">}</span> <span class="co1">// 如果 foo() 返回右值则为未定义行为</span></pre></div>
|
|
</div>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx20">
|
|
<td>
|
|
<p>此问题可用 <span class="t-spar">初始化语句</span> 变通解决:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">for</span> <span class="br0">(</span>T thing <span class="sy1">=</span> foo<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="kw4">auto</span><span class="sy3">&</span> x <span class="sy4">:</span> thing.<span class="me1">items</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="coMULTI">/* ... */</span> <span class="br0">}</span> <span class="co1">// OK</span></pre></div>
|
|
</div>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>如果初始化器(<span class="t-spar">范围表达式</span>)是花括号初始化器列表,那么 <code>__range</code> 被推导为 <span class="t-lc">std::initializer_list<>&&</span>。</p>
|
|
<p>在泛型代码中,使用推导的转发引用,如 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">for</span> <span class="br0">(</span><span class="kw4">auto</span><span class="sy3">&&</span> var <span class="sy4">:</span> sequence<span class="br0">)</span></span></span>,是安全且受推荐的做法。</p>
|
|
<p>如果范围类型拥有名为 <code>begin</code> 的成员和名为 <code>end</code> 的成员,那么使用成员解释方案。其中无视成员是类型、数据成员、函数还是枚举项及其可访问性。从而像 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">class</span> meow <span class="br0">{</span> <span class="kw2">enum</span> <span class="br0">{</span> begin <span class="sy1">=</span> <span class="nu0">1</span>, end <span class="sy1">=</span> <span class="nu0">2</span><span class="br0">}</span><span class="sy4">;</span> <span class="coMULTI">/* 类的剩余部分 */</span> <span class="br0">}</span><span class="sy4">;</span></span></span> 的类不能用于基于范围的 for 循环,即使有命名空间作用域的 begin/end 函数存在。</p>
|
|
<p>虽然通常在 <span class="t-spar">循环语句</span> 中使用声明于 <span class="t-spar">范围变量声明</span> 的变量,但并不要求这么做。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>从 C++17 开始,<span class="t-spar">首表达式</span> 和 <span class="t-spar">尾表达式</span> 的类型不必相同,而且实际上 <span class="t-spar">尾表达式</span> 的类型不必是迭代器:它只需要能与一个迭代器比较是否不等。这允许以一个谓词(例如“迭代器指向空字符”)对范围进行分界。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<p>当基于范围的 for 循环被用于一个具有写时复制语义的(非 const)对象时,它可能会通过(隐式)调用非 const 的 <code>begin()</code> 成员函数触发深层复制。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>如果想要避免这种行为(比如循环实际上不会修改这个对象),可以使用 <span class="t-lc"><a href="cpp-utility-as_const.html">std::as_const</a></span>:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> cow_string <span class="br0">{</span> <span class="coMULTI">/* ... */</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 写时复制的字符串</span>
|
|
cow_string str <span class="sy1">=</span> <span class="coMULTI">/* ... */</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// for(auto x : str) { /* ... */ } // 可能会导致深层复制</span>
|
|
|
|
<span class="kw1">for</span><span class="br0">(</span><span class="kw4">auto</span> x <span class="sy4">:</span> <a href="cpp-utility-as_const.html"><span class="kw1121">std::<span class="me2">as_const</span></span></a><span class="br0">(</span>str<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="coMULTI">/* ... */</span> <span class="br0">}</span></pre></div>
|
|
</div>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.85.B3.E9.94.AE.E8.AF.8D">关键词</span></h3>
|
|
<p><a href="cpp-keyword-for.html"><tt>for</tt></a></p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co2">#include <iostream></span>
|
|
<span class="co2">#include <vector></span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-container-vector.html"><span class="kw1269">std::<span class="me2">vector</span></span></a><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span> v <span class="sy1">=</span> <span class="br0">{</span><span class="nu0">0</span>, <span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span>, <span class="nu0">4</span>, <span class="nu0">5</span><span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">const</span> <span class="kw4">int</span><span class="sy3">&</span> i <span class="sy4">:</span> v<span class="br0">)</span> <span class="co1">// 以 const 引用访问</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> i <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">auto</span> i <span class="sy4">:</span> v<span class="br0">)</span> <span class="co1">// 以值访问,i 的类型是 int</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> i <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">auto</span><span class="sy3">&&</span> i <span class="sy4">:</span> v<span class="br0">)</span> <span class="co1">// 以转发引用访问,i 的类型是 int&</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> i <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">const</span> <span class="kw4">auto</span><span class="sy3">&</span> cv <span class="sy1">=</span> v<span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">auto</span><span class="sy3">&&</span> i <span class="sy4">:</span> cv<span class="br0">)</span> <span class="co1">// 以转发引用访问,i 的类型是 const int&</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> i <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">int</span> n <span class="sy4">:</span> <span class="br0">{</span><span class="nu0">0</span>, <span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span>, <span class="nu0">4</span>, <span class="nu0">5</span><span class="br0">}</span><span class="br0">)</span> <span class="co1">// 初始化器可以是花括号初始化器列表</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> n <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span> a<span class="br0">[</span><span class="br0">]</span> <span class="sy1">=</span> <span class="br0">{</span><span class="nu0">0</span>, <span class="nu0">1</span>, <span class="nu0">2</span>, <span class="nu0">3</span>, <span class="nu0">4</span>, <span class="nu0">5</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">int</span> n <span class="sy4">:</span> a<span class="br0">)</span> <span class="co1">// 初始化器可以是数组</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> n <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="br0">[</span><span class="br0">[</span>maybe_unused<span class="br0">]</span><span class="br0">]</span> <span class="kw4">int</span> n <span class="sy4">:</span> a<span class="br0">)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="nu0">1</span> <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span> <span class="co1">// 不必使用循环变量</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw4">auto</span> n <span class="sy1">=</span> v.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="kw4">auto</span> i <span class="sy4">:</span> v<span class="br0">)</span> <span class="co1">// 初始化语句(C++20)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="sy2">--</span>n <span class="sy2">+</span> i <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw1">typedef</span> decltype<span class="br0">(</span>v<span class="br0">)</span><span class="sy4">::</span><span class="me2">value_type</span> elem_t<span class="sy4">;</span> elem_t i <span class="sy4">:</span> v<span class="br0">)</span>
|
|
<span class="co1">// typedef 声明作为初始化语句(C++20)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> i <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
|
|
<span class="kw1">for</span> <span class="br0">(</span><span class="kw1">using</span> elem_t <span class="sy1">=</span> decltype<span class="br0">(</span>v<span class="br0">)</span><span class="sy4">::</span><span class="me2">value_type</span><span class="sy4">;</span> elem_t i <span class="sy4">:</span> v<span class="br0">)</span>
|
|
<span class="co1">// 别名声明作为初始化语句,同上(C++23)</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> i <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">0 1 2 3 4 5
|
|
0 1 2 3 4 5
|
|
0 1 2 3 4 5
|
|
0 1 2 3 4 5
|
|
0 1 2 3 4 5
|
|
0 1 2 3 4 5
|
|
1 1 1 1 1 1
|
|
5 5 5 5 5 5
|
|
0 1 2 3 4 5
|
|
0 1 2 3 4 5</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E7.BC.BA.E9.99.B7.E6.8A.A5.E5.91.8A">缺陷报告</span></h3>
|
|
<p>下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。</p>
|
|
<table class="dsctable" style="font-size:0.8em">
|
|
<tr>
|
|
<th>DR</th>
|
|
<th>应用于</th>
|
|
<th>出版时的行为</th>
|
|
<th>正确行为</th>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.link/P0962R1">P0962R1</a></td>
|
|
<td>C++11</td>
|
|
<td>只要 begin 和 end 之一存在就使用成员解释方案</td>
|
|
<td>只有在两者都存在时才使用</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-algorithm-for_each.html"><span class="t-lines"><span>for_each</span></span></a></div>
|
|
</div>
|
|
</td>
|
|
<td>应用函数到范围中的元素<br />
|
|
<span class="t-mark">(函数模板)</span></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|