512 lines
54 KiB
HTML
512 lines
54 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>if 语句</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_if skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">if 语句</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>有条件地执行另一条语句。</p>
|
|
<p>用于需要基于运行时<span class="t-rev-inl t-since-cxx17"><span>或编译时</span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span>条件<span class="t-rev-inl t-since-cxx23"><span>或者 if 语句是否在明显常量求值语境下求值</span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>执行的代码。</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><span class="t-spar">属性</span><span class="t-mark">(可选)</span> <code><b>if</b></code> <code><b>constexpr</b></code><span class="t-mark">(可选)</span> <code><b>(</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">true分支语句</span></td>
|
|
<td>(1)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">属性</span><span class="t-mark">(可选)</span> <code><b>if</b></code> <code><b>constexpr</b></code><span class="t-mark">(可选)</span> <code><b>(</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">true分支语句</span> <code><b>else</b></code> <span class="t-spar">false分支语句</span></td>
|
|
<td>(2)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">属性</span><span class="t-mark">(可选)</span> <code><b>if</b></code> <code><b>!</b></code><span class="t-mark">(可选)</span> <code><b>consteval</b></code> <span class="t-spar">复合语句</span></td>
|
|
<td>(3)</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">属性</span><span class="t-mark">(可选)</span> <code><b>if</b></code> <code><b>!</b></code><span class="t-mark">(可选)</span> <code><b>consteval</b></code> <span class="t-spar">复合语句</span> <code><b>else</b></code> <span class="t-spar">语句</span></td>
|
|
<td>(4)</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> 不带 else 分支的 <i>if 语句</i></div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 带 else 分支的 <i>if 语句</i></div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 不带 else 分支的 <i>consteval if 语句</i></div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 带 else 分支的 <i>consteval if 语句</i></div>
|
|
<table class="t-par-begin">
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">属性</span></td>
|
|
<td>-</td>
|
|
<td><span class="t-mark-rev t-since-cxx11">(C++11 起)</span> 任意数量的<a href="cpp-language-attributes.html">属性</a></td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><code><b>constexpr</b></code></td>
|
|
<td>-</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span> 出现时,该语句即为 <i>constexpr if 语句</i></td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">初始化语句</span></td>
|
|
<td>-</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</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>下列之一:
|
|
<ul>
|
|
<li><a href="cpp-language-implicit_conversion.html#.E6.8C.89.E8.AF.AD.E5.A2.83.E8.BD.AC.E6.8D.A2">按语境转换</a>为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 的<a href="cpp-language-expressions.html">表达式</a></li>
|
|
<li>单个非数组变量的带花括号或等号<a href="cpp-language-initialization.html">初始化器</a>的<a href="cpp-language-declarations.html">声明</a></li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">true分支语句</span></td>
|
|
<td>-</td>
|
|
<td>任意<a href="cpp-language-statements.html">语句</a>(通常是复合语句),当 <span class="t-spar">条件</span> 求值为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span> 时执行</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">false分支语句</span></td>
|
|
<td>-</td>
|
|
<td>任意<a href="cpp-language-statements.html">语句</a>(通常是复合语句),当 <span class="t-spar">条件</span> 求值为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">false</span></span></span> 时执行</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">复合语句</span></td>
|
|
<td>-</td>
|
|
<td>任意<a href="cpp-language-statements.html#.E5.A4.8D.E5.90.88.E8.AF.AD.E5.8F.A5">复合语句</a>,在以下场合执行:
|
|
<ul>
|
|
<li>if 语句在<a href="cpp-language-constant_expression.html#.E6.98.8E.E6.98.BE.E5.B8.B8.E9.87.8F.E6.B1.82.E5.80.BC.E7.9A.84.E8.A1.A8.E8.BE.BE.E5.BC.8F">明显常量求值语境</a>下求值,如果 <code>consteval</code> 未前附 <code>!</code>(<code>if consteval</code>)</li>
|
|
<li>if 语句不在明显常量求值语境下求值,如果 <code>consteval</code> 前附 <code>!</code>(<code>if !consteval</code>)</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr class="t-par">
|
|
<td><span class="t-spar">语句</span></td>
|
|
<td>-</td>
|
|
<td>任意<a href="cpp-language-statements.html">语句</a>(只能是复合语句,见<a href="cpp-language-if.html#consteval_if">下文</a>),在以下场合执行:
|
|
<ul>
|
|
<li>if 语句不在<a href="cpp-language-constant_expression.html#.E6.98.8E.E6.98.BE.E5.B8.B8.E9.87.8F.E6.B1.82.E5.80.BC.E7.9A.84.E8.A1.A8.E8.BE.BE.E5.BC.8F">明显常量求值语境</a>下求值,如果 <code>consteval</code> 未前附 <code>!</code>(<code>if consteval else</code>)</li>
|
|
<li>if 语句在明显常量求值语境下求值,如果 <code>consteval</code> 前附 <code>!</code>(<code>if !consteval else</code>)</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>如果 <span class="t-spar">条件</span> 在转换到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 后产生 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span>,那么执行 <span class="t-spar">true分支语句</span>。</p>
|
|
<p>如果 if 语句存在 else 部分,且 <span class="t-spar">条件</span> 在转换到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 后产生 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">false</span></span></span>,那么执行 <span class="t-spar">false分支语句</span>。</p>
|
|
<p>在 if 语句的第二形式(包含 else)中,如果 <span class="t-spar">true分支语句</span> 也是 if 语句,那么内层 if 语句必须也含有 else 部分(换言之,在嵌套 if 语句中 else 关联到最近的尚未有 else 的 if)。</p>
|
|
<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="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="co1">// 带 else 子句的简单 if 语句</span>
|
|
<span class="kw4">int</span> i <span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>i <span class="sy1">></span> <span class="nu0">2</span><span class="br0">)</span> <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> i <span class="sy1"><<</span> <span class="st0">" 大于 2<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="kw1">else</span> <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> i <span class="sy1"><<</span> <span class="st0">" 不大于 2<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="co1">// 嵌套 if 语句</span>
|
|
<span class="kw4">int</span> j <span class="sy1">=</span> <span class="nu0">1</span><span class="sy4">;</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>i <span class="sy1">></span> <span class="nu0">1</span><span class="br0">)</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>j <span class="sy1">></span> <span class="nu0">2</span><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> i <span class="sy1"><<</span> <span class="st0">" > 1 且 "</span> <span class="sy1"><<</span> j <span class="sy1"><<</span> <span class="st0">" > 2<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
<span class="kw1">else</span> <span class="co1">// 此 else 属于 if (j > 2), 而不是 if (i > 1)</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">" > 1 且 "</span> <span class="sy1"><<</span> j <span class="sy1"><<</span> <span class="st0">" <= 2<span class="es1">\n</span>"</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 以下声明可用于含 dynamic_cast 的条件</span>
|
|
<span class="kw1">struct</span> Base <span class="br0">{</span>
|
|
<span class="kw1">virtual</span> ~Base<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">struct</span> Derived <span class="sy4">:</span> Base <span class="br0">{</span>
|
|
<span class="kw4">void</span> df<span class="br0">(</span><span class="br0">)</span> <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="st0">"df()<span class="es1">\n</span>"</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
Base<span class="sy2">*</span> bp1 <span class="sy1">=</span> new Base<span class="sy4">;</span>
|
|
Base<span class="sy2">*</span> bp2 <span class="sy1">=</span> new Derived<span class="sy4">;</span>
|
|
|
|
<span class="kw1">if</span> <span class="br0">(</span>Derived<span class="sy2">*</span> p <span class="sy1">=</span> <span class="kw1">dynamic_cast</span><span class="sy1"><</span>Derived<span class="sy2">*</span><span class="sy1">></span><span class="br0">(</span>bp1<span class="br0">)</span><span class="br0">)</span> <span class="co1">// 转型失败,返回 nullptr</span>
|
|
p<span class="sy2">-</span><span class="sy1">></span>df<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 不执行</span>
|
|
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw4">auto</span> p <span class="sy1">=</span> <span class="kw1">dynamic_cast</span><span class="sy1"><</span>Derived<span class="sy2">*</span><span class="sy1">></span><span class="br0">(</span>bp2<span class="br0">)</span><span class="br0">)</span> <span class="co1">// 转型成功</span>
|
|
p<span class="sy2">-</span><span class="sy1">></span>df<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 执行</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">2 不大于 2
|
|
2 > 1 且 1 <= 2
|
|
df()</pre></div>
|
|
</div>
|
|
</div>
|
|
<p><br /></p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<h4><span class="mw-headline" id=".E5.B8.A6.E5.88.9D.E5.A7.8B.E5.8C.96.E5.99.A8.E7.9A.84_if_.E8.AF.AD.E5.8F.A5">带初始化器的 if 语句</span></h4>
|
|
<p>如果使用 <span class="t-spar">初始化语句</span>,那么 if 语句等价于</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>{</b></code><br />
|
|
<dl>
|
|
<dd><span class="t-spar">初始化语句</span><br /></dd>
|
|
<dd><code><b>if</b></code> <code><b>constexpr</b></code><span class="t-mark">(可选)</span> <code><b>(</b></code> <span class="t-spar">条件</span> <code><b>)</b></code><br />
|
|
<dl>
|
|
<dd><span class="t-spar">true分支语句</span><br /></dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|
|
<p><code><b>}</b></code></p>
|
|
</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>
|
|
<p>或</p>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>{</b></code><br />
|
|
<dl>
|
|
<dd><span class="t-spar">初始化语句</span><br /></dd>
|
|
<dd><code><b>if</b></code> <code><b>constexpr</b></code><span class="t-mark">(可选)</span> <code><b>(</b></code> <span class="t-spar">条件</span> <code><b>)</b></code><br />
|
|
<dl>
|
|
<dd><span class="t-spar">true分支语句</span><br /></dd>
|
|
</dl>
|
|
</dd>
|
|
<dd><code><b>else</b></code>
|
|
<dl>
|
|
<dd><span class="t-spar">false分支语句</span><br /></dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|
|
<p><code><b>}</b></code></p>
|
|
</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>
|
|
<p>但 <span class="t-spar">初始化语句</span> 所声明的名字(如果 <span class="t-spar">初始化语句</span> 是声明)和 <span class="t-spar">条件</span> 所声明的名字(如果 <span class="t-spar">条件</span> 是声明)处于同一作用域中,同时也是两条 <span class="t-spar">语句</span> 所在的作用域。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><a href="cpp-container-map.html"><span class="kw1281">std::<span class="me2">map</span></span></a><span class="sy1"><</span><span class="kw4">int</span>, <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy1">></span> m<span class="sy4">;</span>
|
|
<a href="cpp-thread-mutex.html"><span class="kw2154">std::<span class="me2">mutex</span></span></a> mx<span class="sy4">;</span>
|
|
<span class="kw4">extern</span> <span class="kw4">bool</span> shared_flag<span class="sy4">;</span> <span class="co1">// 由 mx 保证</span>
|
|
<span class="kw4">int</span> demo<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw4">auto</span> it <span class="sy1">=</span> m.<span class="me1">find</span><span class="br0">(</span><span class="nu0">10</span><span class="br0">)</span><span class="sy4">;</span> it <span class="sy3">!</span><span class="sy1">=</span> m.<span class="me1">end</span><span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> it<span class="sy2">-</span><span class="sy1">></span>second.<span class="me1">size</span><span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw4">char</span> buf<span class="br0">[</span><span class="nu0">10</span><span class="br0">]</span><span class="sy4">;</span> <a href="cpp-io-c-fgets.html"><span class="kw1823">std::<span class="me2">fgets</span></span></a><span class="br0">(</span>buf, <span class="nu0">10</span>, <span class="kw2">stdin</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> m<span class="br0">[</span><span class="nu0">0</span><span class="br0">]</span> <span class="sy2">+</span><span class="sy1">=</span> buf<span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span><a href="cpp-thread-lock_guard.html"><span class="kw2166">std::<span class="me2">lock_guard</span></span></a> lock<span class="br0">(</span>mx<span class="br0">)</span><span class="sy4">;</span> shared_flag<span class="br0">)</span> <span class="br0">{</span> unsafe_ping<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span> shared_flag <span class="sy1">=</span> <span class="kw2">false</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw4">int</span> s<span class="sy4">;</span> <span class="kw4">int</span> count <span class="sy1">=</span> ReadBytesWithSignal<span class="br0">(</span><span class="sy3">&</span>s<span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span> publish<span class="br0">(</span>count<span class="br0">)</span><span class="sy4">;</span> raise<span class="br0">(</span>s<span class="br0">)</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw4">auto</span> keywords <span class="sy1">=</span> <span class="br0">{</span><span class="st0">"if"</span>, <span class="st0">"for"</span>, <span class="st0">"while"</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<a href="cpp-algorithm-all_any_none_of.html"><span class="kw1566">std::<span class="me2">any_of</span></span></a><span class="br0">(</span>keywords.<span class="me1">begin</span><span class="br0">(</span><span class="br0">)</span>, keywords.<span class="me1">end</span><span class="br0">(</span><span class="br0">)</span>,
|
|
<span class="br0">[</span><span class="sy3">&</span>s<span class="br0">]</span><span class="br0">(</span><span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> kw<span class="br0">)</span> <span class="br0">{</span> <span class="kw1">return</span> s <span class="sy1">==</span> kw<span class="sy4">;</span> <span class="br0">}</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<a href="cpp-io-cerr.html"><span class="kw1760">std::<span class="me2">cerr</span></span></a> <span class="sy1"><<</span> <span class="st0">"Token 不能是关键词<span class="es1">\n</span>"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<h4><span class="mw-headline" id="constexpr_if">constexpr if</span></h4>
|
|
<p>以 <code><b>if constexpr</b></code> 开始的语句被称为 <i>constexpr if 语句</i>。</p>
|
|
<p>在 constexpr if 语句中,<span class="t-spar">条件</span> 的值必须是<span class="t-rev-inl t-until-cxx23"><span><a href="cpp-language-constant_expression.html#.E7.BB.8F.E8.BD.AC.E6.8D.A2.E7.9A.84.E5.B8.B8.E9.87.8F.E8.A1.A8.E8.BE.BE.E5.BC.8F">可按语境转换到 <code>bool</code> 类型的经转换常量表达式</a></span> <span><span class="t-mark-rev t-until-cxx23">(C++23 前)</span></span></span><span class="t-rev-inl t-since-cxx23"><span><a href="cpp-language-implicit_conversion.html#.E6.8C.89.E8.AF.AD.E5.A2.83.E8.BD.AC.E6.8D.A2">按语境转换到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 的表达式</a>,其中转换为<a href="cpp-language-constant_expression.html">常量表达式</a></span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>。如果它的值是 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw2">true</span></span></span>,那么舍弃 <span class="t-spar">false分支语句</span>(如果存在),否则舍弃 <span class="t-spar">true分支语句</span>。</p>
|
|
<p>被舍弃语句中的 return 语句不参与函数返回类型推导:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">template</span> <span class="sy1"><</span><span class="kw1">typename</span> T<span class="sy1">></span>
|
|
<span class="kw4">auto</span> get_value<span class="br0">(</span>T t<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="kw4">constexpr</span> <span class="br0">(</span><a href="cpp-types-is_pointer.html"><span class="kw463">std::<span class="me2">is_pointer_v</span></span></a><span class="sy1"><</span>T<span class="sy1">></span><span class="br0">)</span>
|
|
<span class="kw1">return</span> <span class="sy2">*</span>t<span class="sy4">;</span> <span class="co1">// 对 T = int* 推导返回类型为 int</span>
|
|
<span class="kw1">else</span>
|
|
<span class="kw1">return</span> t<span class="sy4">;</span> <span class="co1">// 对 T = int 推导返回类型为 int</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>被舍弃语句可以 <a href="cpp-language-definition.html#.E5.8D.95.E4.B8.80.E5.AE.9A.E4.B9.89.E8.A7.84.E5.88.99.EF.BC.88ODR.EF.BC.89">ODR 式使用</a>未定义的变量:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw4">extern</span> <span class="kw4">int</span> x<span class="sy4">;</span> <span class="co1">// 不需要 x 的定义</span>
|
|
<span class="kw4">int</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="kw4">constexpr</span> <span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span>
|
|
<span class="kw1">return</span> <span class="nu0">0</span><span class="sy4">;</span>
|
|
<span class="kw1">else</span> <span class="kw1">if</span> <span class="br0">(</span>x<span class="br0">)</span>
|
|
<span class="kw1">return</span> x<span class="sy4">;</span>
|
|
<span class="kw1">else</span>
|
|
<span class="kw1">return</span> <span class="sy2">-</span>x<span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>如果 constexpr if 语句在<a href="cpp-language-templates.html#.E6.A8.A1.E6.9D.BF.E5.8C.96.E5.AE.9E.E4.BD.93">模板实体</a>内出现,且如果 <span class="t-spar">条件</span> 在实例化后不是<a href="cpp-language-dependent_name.html#.E5.80.BC.E5.BE.85.E5.86.B3.E8.A1.A8.E8.BE.BE.E5.BC.8F">值待决</a>的,那么外围模板被实例化时不会实例化被舍弃语句。</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">typename</span> T, <span class="kw1">typename</span> ... <span class="me1">Rest</span><span class="sy1">></span>
|
|
<span class="kw4">void</span> g<span class="br0">(</span>T<span class="sy3">&&</span> p, Rest<span class="sy3">&&</span> ...<span class="me1">rs</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="co1">// ... 处理 p</span>
|
|
<span class="kw1">if</span> <span class="kw4">constexpr</span> <span class="br0">(</span>sizeof...<span class="br0">(</span>rs<span class="br0">)</span> <span class="sy1">></span> <span class="nu0">0</span><span class="br0">)</span>
|
|
g<span class="br0">(</span>rs...<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 始终不会对空实参列表实例化。</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>在模板外,被舍弃语句受到完整的检查。<code>if constexpr</code> 不是 <a href="cpp-preprocessor-conditional.html"><tt>#if</tt></a> 预处理指令的替代品:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="kw4">constexpr</span><span class="br0">(</span><span class="kw2">false</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">int</span> i <span class="sy1">=</span> <span class="nu0">0</span><span class="sy4">;</span>
|
|
<span class="kw4">int</span> <span class="sy2">*</span>p <span class="sy1">=</span> i<span class="sy4">;</span> <span class="co1">// 在被舍弃语句中仍为错误</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>注意:实例化后仍为值待决的一个例子是嵌套模板,例如:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">class</span> T<span class="sy1">></span> <span class="kw4">void</span> g<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">auto</span> lm <span class="sy1">=</span> <span class="br0">[</span><span class="br0">]</span><span class="br0">(</span><span class="kw4">auto</span> p<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="kw4">constexpr</span> <span class="br0">(</span>sizeof<span class="br0">(</span>T<span class="br0">)</span> <span class="sy1">==</span> <span class="nu0">1</span> <span class="sy3">&&</span> sizeof p <span class="sy1">==</span> <span class="nu0">1</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="co1">// 此条件在 g<T> 实例化后仍为值待决的</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:看起来 <a rel="nofollow" class="external text" href="https://wg21.link/P0588R1">P0588R1</a> 改变了状况。</td>
|
|
</tr>
|
|
</table>
|
|
<p>注意:被舍弃语句不能对所有特化均非良构:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">template</span> <span class="sy1"><</span><span class="kw1">typename</span> T<span class="sy1">></span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="kw4">constexpr</span> <span class="br0">(</span><a href="cpp-types-is_arithmetic.html"><span class="kw483">std::<span class="me2">is_arithmetic_v</span></span></a><span class="sy1"><</span>T<span class="sy1">></span><span class="br0">)</span>
|
|
<span class="co1">// ...</span>
|
|
<span class="kw1">else</span>
|
|
static_assert<span class="br0">(</span><span class="kw2">false</span>, <span class="st0">"必须是算术类型"</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 非良构:该语句对于所有 T 都非法</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>对这种万应语句的常用变通方案,是一条始终为 false 的类型待决表达式:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">class</span> T<span class="sy1">></span> <span class="kw1">struct</span> dependent_false <span class="sy4">:</span> <a href="cpp-types-integral_constant.html"><span class="kw650">std::<span class="me2">false_type</span></span></a> <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">template</span> <span class="sy1"><</span><span class="kw1">typename</span> T<span class="sy1">></span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="kw4">constexpr</span> <span class="br0">(</span><a href="cpp-types-is_arithmetic.html"><span class="kw483">std::<span class="me2">is_arithmetic_v</span></span></a><span class="sy1"><</span>T<span class="sy1">></span><span class="br0">)</span>
|
|
<span class="co1">// ...</span>
|
|
<span class="kw1">else</span>
|
|
static_assert<span class="br0">(</span>dependent_false<span class="sy1"><</span>T<span class="sy1">></span><span class="sy4">::</span><span class="me2">value</span>, <span class="st0">"必须是算术类型"</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>在 constexpr if 的子语句中出现的标号(<a href="cpp-language-goto.html">goto 目标</a>、<code>case</code> 标号和 <code>default:</code>),只能在同一子语句中(由 <a href="cpp-language-switch.html"><code>switch</code></a> 或 <a href="cpp-language-goto.html"><code>goto</code></a>)引用。</p>
|
|
<p>注意:能以 <a href="cpp-language-typedef.html">typedef 声明</a><span class="t-rev-inl t-since-cxx23"><span>或<a href="cpp-language-type_alias.html">别名声明</a></span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>为 constexpr if 语句的初始化语句以减少类型别名的作用域。</p>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:暂无示例</td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx23">
|
|
<td>
|
|
<h4><span class="mw-headline" id="consteval_if">consteval if</span></h4>
|
|
<p>以 <code><b>if consteval</b></code> 开始的语句被称为 <i>consteval if 语句</i>。在 consteval if 语句中 <span class="t-spar">复合语句</span> 和 <span class="t-spar">语句</span> (如果存在)必须是复合语句。</p>
|
|
<p>即使 <span class="t-spar">语句</span> 不是复合语句,它也会被视为 consteval if 语句的一部分(因此产生编译错误):</p>
|
|
<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="kw4">constexpr</span> <span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">bool</span> b<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="kw2">true</span><span class="br0">)</span>
|
|
<span class="kw1">if</span> consteval <span class="br0">{</span> <span class="br0">}</span>
|
|
<span class="kw1">else</span> <span class="sy4">;</span> <span class="co1">// 错误:不是复合语句,else 不与外层 if 关联</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
<p>如果在<a href="cpp-language-constant_expression.html#.E6.98.8E.E6.98.BE.E5.B8.B8.E9.87.8F.E6.B1.82.E5.80.BC.E7.9A.84.E8.A1.A8.E8.BE.BE.E5.BC.8F">明显常量求值语境</a>中求值 consteval if 语句,那么执行 <span class="t-spar">复合语句</span> 。否则在 <span class="t-spar">语句</span> 存在时执行它。</p>
|
|
<p>在 consteval if 语句中出现的 <code><b>case</b></code> 或 <code><b>default</b></code> 标签必须关联到同一 if 语句中的 <a href="cpp-language-switch.html"><code>switch</code></a> 语句。在 consteval if 语句中声明的<a href="cpp-language-goto.html">标签</a>必须只关联到同一子语句中的语句。</p>
|
|
<p>如果语句以 <code><b>if !consteval</b></code> 开始,那么 <span class="t-spar">复合语句</span> 与 <span class="t-spar">语句</span> (如果存在)必须都是复合语句。这种语句不被认为是 consteval if 语句,但它等价于 consteval if 语句:</p>
|
|
<ul>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">if</span> <span class="sy3">!</span>consteval <span class="br0">{</span><span class="coMULTI">/*语句*/</span><span class="br0">}</span></span></span> 等价于 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">if</span> consteval <span class="br0">{</span><span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span><span class="coMULTI">/*语句*/</span><span class="br0">}</span></span></span> 。</li>
|
|
<li><span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">if</span> <span class="sy3">!</span>consteval <span class="br0">{</span><span class="coMULTI">/*语句1*/</span><span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span><span class="coMULTI">/*语句2*/</span><span class="br0">}</span></span></span> 等价于 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">if</span> consteval <span class="br0">{</span><span class="coMULTI">/*语句2*/</span><span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span><span class="coMULTI">/*语句1*/</span><span class="br0">}</span></span></span> 。</li>
|
|
</ul>
|
|
<p>consteval if 语句中的 <span class="t-spar">复合语句</span> (或否定形式中的 <span class="t-spar">语句</span>)是<a href="cpp-language-consteval.html">立即函数语境</a>,在其中对立即函数的调用不需要是常量表达式。</p>
|
|
<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 <cmath></span>
|
|
<span class="co2">#include <cstdint></span>
|
|
<span class="co2">#include <cstring></span>
|
|
<span class="co2">#include <iostream></span>
|
|
|
|
<span class="kw4">constexpr</span> <span class="kw4">bool</span> is_constant_evaluated<span class="br0">(</span><span class="br0">)</span> <span class="kw1">noexcept</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> consteval <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">true</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">false</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">constexpr</span> <span class="kw4">bool</span> is_runtime_evaluated<span class="br0">(</span><span class="br0">)</span> <span class="kw1">noexcept</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> not consteval <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">true</span><span class="sy4">;</span> <span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span> <span class="kw1">return</span> <span class="kw2">false</span><span class="sy4">;</span> <span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
consteval <a href="cpp-types-integer.html"><span class="kw123">std::<span class="me2">uint64_t</span></span></a> ipow_ct<span class="br0">(</span><a href="cpp-types-integer.html"><span class="kw123">std::<span class="me2">uint64_t</span></span></a> base, <a href="cpp-types-integer.html"><span class="kw120">std::<span class="me2">uint8_t</span></span></a> exp<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span><span class="sy3">!</span>base<span class="br0">)</span> <span class="kw1">return</span> base<span class="sy4">;</span>
|
|
<a href="cpp-types-integer.html"><span class="kw123">std::<span class="me2">uint64_t</span></span></a> res<span class="br0">{</span><span class="nu0">1</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">while</span> <span class="br0">(</span>exp<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> <span class="br0">(</span>exp <span class="sy3">&</span> <span class="nu0">1</span><span class="br0">)</span> res <span class="sy2">*</span><span class="sy1">=</span> base<span class="sy4">;</span>
|
|
exp <span class="sy2">/</span><span class="sy1">=</span> <span class="nu0">2</span><span class="sy4">;</span>
|
|
base <span class="sy2">*</span><span class="sy1">=</span> base<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw1">return</span> res<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">constexpr</span> <a href="cpp-types-integer.html"><span class="kw123">std::<span class="me2">uint64_t</span></span></a> ipow<span class="br0">(</span><a href="cpp-types-integer.html"><span class="kw123">std::<span class="me2">uint64_t</span></span></a> base, <a href="cpp-types-integer.html"><span class="kw120">std::<span class="me2">uint8_t</span></span></a> exp<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">if</span> consteval <span class="br0">{</span> <span class="co1">// 使用编译时友好的算法</span>
|
|
<span class="kw1">return</span> ipow_ct<span class="br0">(</span>base, exp<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw1">else</span> <span class="br0">{</span> <span class="co1">// 使用运行时求值</span>
|
|
<span class="kw1">return</span> <a href="cpp-numeric-math-pow.html"><span class="kw1332">std::<span class="me2">pow</span></span></a><span class="br0">(</span>base, exp<span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="kw4">int</span>, <span class="kw4">const</span> <span class="kw4">char</span><span class="sy2">*</span> argv<span class="br0">[</span><span class="br0">]</span><span class="br0">)</span> <span class="br0">{</span>
|
|
static_assert<span class="br0">(</span>ipow<span class="br0">(</span><span class="nu0">0</span>,<span class="nu0">10</span><span class="br0">)</span> <span class="sy1">==</span> <span class="nu0">0</span> <span class="sy3">&&</span> ipow<span class="br0">(</span><span class="nu0">2</span>,<span class="nu0">10</span><span class="br0">)</span> <span class="sy1">==</span> <span class="nu0">1024</span><span class="br0">)</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> ipow<span class="br0">(</span><a href="cpp-string-byte-strlen.html"><span class="kw1145">std::<span class="me2">strlen</span></span></a><span class="br0">(</span>argv<span class="br0">[</span><span class="nu0">0</span><span class="br0">]</span><span class="br0">)</span>, <span class="nu0">3</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>如果 <span class="t-spar">true分支语句</span> 或 <span class="t-spar">false分支语句</span> 不是复合语句,那么按如同是复合语句一样处理:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">if</span> <span class="br0">(</span>x<span class="br0">)</span>
|
|
<span class="kw4">int</span> i<span class="sy4">;</span>
|
|
<span class="co1">// i 不再在作用域中</span></pre></div>
|
|
</div>
|
|
<p>与下面相同</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">if</span> <span class="br0">(</span>x<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">int</span> i<span class="sy4">;</span>
|
|
<span class="br0">}</span> <span class="co1">// i 不再在作用域中</span></pre></div>
|
|
</div>
|
|
<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">if</span> <span class="br0">(</span><span class="kw4">int</span> x <span class="sy1">=</span> f<span class="br0">(</span><span class="br0">)</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">int</span> x<span class="sy4">;</span> <span class="co1">// 错误:重复声明了 x</span>
|
|
<span class="br0">}</span> <span class="kw1">else</span> <span class="br0">{</span>
|
|
<span class="kw4">int</span> x<span class="sy4">;</span> <span class="co1">// 错误:重复声明了 x</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>如果通过 <a href="cpp-language-goto.html"><code>goto</code></a> 或 <span class="t-lc">longjmp</span> 进入 <span class="t-spar">true分支语句</span>,那么不执行 <span class="t-spar">false分支语句</span>。</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17 t-until-cxx23">
|
|
<td>
|
|
<p>constexpr if 语句的 <span class="t-spar">条件</span> 中不允许内建转换,除了到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 的非<a href="cpp-language-list_initialization.html#.E7.AA.84.E5.8C.96">窄化</a><a href="cpp-language-implicit_conversion.html#.E6.95.B4.E5.9E.8B.E8.BD.AC.E6.8D.A2">整型转换</a>。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span><br />
|
|
<span class="t-mark-rev t-until-cxx23">(C++23 前)</span></td>
|
|
</tr>
|
|
</table>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<p>不允许 <a href="cpp-language-switch.html"><code>switch</code></a> 和 <a href="cpp-language-goto.html"><code>goto</code></a> 跳入 constexpr if 语句<span class="t-rev-inl t-since-cxx23"><span>或 consteval if 语句</span> <span><span class="t-mark-rev t-since-cxx23">(C++23 起)</span></span></span>的分支。</p>
|
|
</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-if.html"><tt>if</tt></a>, <a href="cpp-keyword-else.html"><tt>else</tt></a>, <a href="cpp-keyword-constexpr.html"><tt>constexpr</tt></a>, <a href="cpp-keyword-consteval.html"><tt>consteval</tt></a></p>
|
|
<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.cmeerw.net/cwg/issue631">CWG 631</a></td>
|
|
<td>C++98</td>
|
|
<td>如果通过标签抵达第一子语句则控制流未指明</td>
|
|
<td>与 C 的行为一致</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin"></table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|