400 lines
46 KiB
HTML
400 lines
46 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>列表初始化 (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_list_initialization skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">列表初始化 <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>从 <span class="t-spar">花括号初始化器列表</span> 列表初始化对象</p>
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<h4><span class="mw-headline" id=".E7.9B.B4.E6.8E.A5.E5.88.97.E8.A1.A8.E5.88.9D.E5.A7.8B.E5.8C.96">直接列表初始化</span></h4>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">T</span> <span class="t-spar">对象</span> <code><b>{</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>};</b></code></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">T</span> <code><b>{</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>}</b></code></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><code><b>new</b></code> <span class="t-spar">T</span> <code><b>{</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>}</b></code></td>
|
|
<td>(3)</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> <code><b>{</b></code> <span class="t-spar">T</span> <span class="t-spar">成员</span> <code><b>{</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>}; };</b></code></td>
|
|
<td>(4)</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><code><b>::</b></code><span class="t-spar">类</span><code><b>() :</b></code> <span class="t-spar">成员</span><code><b>{</b></code><span class="t-spar">实参1, 实参2, ...</span><code><b>} {...</b></code></td>
|
|
<td>(5)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<h4><span class="mw-headline" id=".E5.A4.8D.E5.88.B6.E5.88.97.E8.A1.A8.E5.88.9D.E5.A7.8B.E5.8C.96">复制列表初始化</span></h4>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><span class="t-spar">T</span> <span class="t-spar">对象</span> <code><b>= {</b></code><span class="t-spar">实参1, 实参2, ...</span><code><b>};</b></code></td>
|
|
<td>(6)</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><code><b>( {</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>} )</b></code></td>
|
|
<td>(7)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td><code><b>return {</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>} ;</b></code></td>
|
|
<td>(8)</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><code><b>[ {</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>} ]</b></code></td>
|
|
<td>(9)</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> <code><b>=</b></code> <code><b>{</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>}</b></code></td>
|
|
<td>(10)</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">U</span><code><b>( {</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>} )</b></code></td>
|
|
<td>(11)</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> <code><b>{</b></code> <span class="t-spar">T</span> <span class="t-spar">成员</span> <code><b>=</b></code> <code><b>{</b></code> <span class="t-spar">实参1, 实参2, ...</span> <code><b>}; };</b></code></td>
|
|
<td>(12)</td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<p>在下列情形进行列表初始化:</p>
|
|
<ul>
|
|
<li>直接列表初始化(考虑 explicit 和非 explicit 构造函数)</li>
|
|
</ul>
|
|
<div class="t-li1"><span class="t-li">1)</span> 以 <span class="t-spar">花括号初始化器列表</span>(即花括号环绕的可以为空的表达式或 <span class="t-spar">花括号初始化器列表</span> 的列表)初始化具名变量</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 以 <span class="t-spar">花括号初始化器列表</span> 初始化无名临时量</div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 以 <a href="cpp-language-new.html">new 表达式</a>初始化具有动态存储期的对象,它的初始化器是 <span class="t-spar">花括号初始化器列表</span> 列表</div>
|
|
<div class="t-li1"><span class="t-li">4)</span> 在不使用等号的非静态<a href="cpp-language-data_members.html#.E6.88.90.E5.91.98.E5.88.9D.E5.A7.8B.E5.8C.96">数据成员初始化器</a>中</div>
|
|
<div class="t-li1"><span class="t-li">5)</span> 在构造函数的<a href="cpp-language-initializer_list.html" class="mw-redirect">成员初始化列表</a>中,如果使用 <span class="t-spar">花括号初始化器列表</span></div>
|
|
<ul>
|
|
<li>复制列表初始化(考虑 explicit 和非 explicit 构造函数,但只能调用非 explicit 构造函数)</li>
|
|
</ul>
|
|
<div class="t-li1"><span class="t-li">6)</span> 以等号后的 <span class="t-spar">花括号初始化器列表</span> 初始化具名变量</div>
|
|
<div class="t-li1"><span class="t-li">7)</span> 函数调用表达式中,以 <span class="t-spar">花括号初始化器列表</span> 为实参,以列表初始化对函数形参初始化</div>
|
|
<div class="t-li1"><span class="t-li">8)</span> 在以 <span class="t-spar">花括号初始化器列表</span> 为返回表达式的 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">return</span></span></span> 语句中,以列表初始化对返回的对象初始化</div>
|
|
<div class="t-li1"><span class="t-li">9)</span> 在具有用户定义的 <code>operator[]</code> 的<a href="cpp-language-operator_member_access.html#.E5.86.85.E5.BB.BA.E7.9A.84.E4.B8.8B.E6.A0.87.E8.BF.90.E7.AE.97.E7.AC.A6">下标表达式</a>中,以列表初始化对重载运算符的形参初始化</div>
|
|
<div class="t-li1"><span class="t-li">10)</span> 在<a href="cpp-language-operator_assignment.html">赋值表达式</a>中,以列表初始化对重载的运算符的形参初始化</div>
|
|
<div class="t-li1"><span class="t-li">11)</span> <a href="cpp-language-explicit_cast.html">函数式转型表达式</a>或其他构造函数调用,其中 <span class="t-spar">花括号初始化器列表</span> 用作构造函数实参。以复制初始化对构造函数的形参初始化(注意:此例中的类型 U 不是被列表初始化的类型;但 U 的构造函数的形参是)</div>
|
|
<div class="t-li1"><span class="t-li">12)</span> 在使用等号的非静态<a href="cpp-language-data_members.html#.E6.88.90.E5.91.98.E5.88.9D.E5.A7.8B.E5.8C.96">数据成员初始化器</a>中</div>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p><code>T</code> 类型的对象的列表初始化的效果是:</p>
|
|
<ul>
|
|
<li>如果 <code>T</code> 是聚合类且 <span class="t-spar">花括号初始化器列表</span> 拥有单个(可有 cv 限定的)相同类型或派生类型的元素,那么从该元素初始化对象(对于复制列表初始化为<a href="cpp-language-copy_initialization.html">复制初始化</a>,对于直接列表初始化为<a href="cpp-language-direct_initialization.html">直接初始化</a>)。</li>
|
|
<li>否则,如果 <code>T</code> 是字符数组且初始化器列表拥有单个类型适当的字符串字面量元素,那么照常<a href="cpp-language-aggregate_initialization.html#.E5.AD.97.E7.AC.A6.E6.95.B0.E7.BB.84">从字符串字面量初始化</a>数组。</li>
|
|
<li>否则,如果 <code>T</code> 是<a href="cpp-language-aggregate_initialization.html">聚合类型</a>,那么进行<a href="cpp-language-aggregate_initialization.html">聚合初始化</a>。</li>
|
|
</ul>
|
|
<ul>
|
|
<li>否则,如果 <span class="t-spar">花括号初始化器列表</span> 列表为空,且 <code>T</code> 是拥有默认构造函数的类类型,那么进行<a href="cpp-language-value_initialization.html">值初始化</a>。</li>
|
|
</ul>
|
|
<ul>
|
|
<li>否则,如果 <code>T</code> 是 <span class="t-lc"><a href="cpp-utility-initializer_list.html">std::initializer_list</a></span> 的特化,则依据其语境以 <span class="t-spar">花括号初始化器列表</span> <span class="t-rev-inl t-until-cxx17"><span>所初始化的同类型的纯右值</span> <span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span>直接初始化或复制初始化该 <code>T</code> 对象。</li>
|
|
</ul>
|
|
<ul>
|
|
<li>否则,以两个阶段考虑 <code>T</code> 的构造函数:</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>检验所有接受 <span class="t-lc"><a href="cpp-utility-initializer_list.html">std::initializer_list</a></span> 作为其唯一实参,或如果剩余实参都具有默认值则为其首个实参的构造函数,并通过<a href="cpp-language-overload_resolution.html">重载决议</a>与单个 <span class="t-lc"><a href="cpp-utility-initializer_list.html">std::initializer_list</a></span> 类型的实参进行匹配。</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>如果上一个阶段未产生匹配,那么 <code>T</code> 的所有构造函数都参与针对由 <span class="t-spar">花括号初始化器列表</span> 的各元素所组成的实参集的<a href="cpp-language-overload_resolution.html#.E5.88.97.E8.A1.A8.E5.88.9D.E5.A7.8B.E5.8C.96.E4.B8.AD.E7.9A.84.E9.9A.90.E5.BC.8F.E8.BD.AC.E6.8D.A2.E5.BA.8F.E5.88.97">重载决议</a>,它会受到只允许非窄化转换的限制。如果这个阶段为复制列表初始化产生的最佳匹配是 explicit 构造函数,那么编译失败(注意:简单复制初始化中完全不考虑 explicit 构造函数)。</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx17">
|
|
<td>
|
|
<ul>
|
|
<li>否则,如果:
|
|
<ul>
|
|
<li><code>T</code> 是拥有固定底层类型 <code>U</code> (如果枚举为有作用域且未手工指定其底层类型则为 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">int</span></span></span>)的<a href="cpp-language-enum.html">枚举类型</a>,且</li>
|
|
<li>初始化为直接列表初始化,且</li>
|
|
<li><span class="t-spar">花括号初始化器列表</span> 仅拥有一个能隐式转换成 <code>U</code> 的初始化器 <span class="t-c"><span class="mw-geshi cpp source-cpp">v</span></span>,且</li>
|
|
<li>从 <span class="t-c"><span class="mw-geshi cpp source-cpp">v</span></span> 到 <code>U</code> 的转换不是窄化,</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>那么以将 <span class="t-c"><span class="mw-geshi cpp source-cpp">v</span></span> 转换到 <code>U</code> 的结果初始化该枚举。</dd>
|
|
</dl>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<ul>
|
|
<li>否则(如果 <code>T</code> 不是类类型),如果 <span class="t-spar">花括号初始化器列表</span> 仅拥有一个元素,且 <code>T</code> 要么不是引用类型,要么是引用类型而其所引用的类型与该元素的类型相同或为其基类,那么<a href="cpp-language-direct_initialization.html">直接初始化</a>(直接列表初始化时)或<a href="cpp-language-copy_initialization.html">复制初始化</a>(复制列表初始化时)这个 <code>T</code>,但不允许窄化转换。</li>
|
|
</ul>
|
|
<ul>
|
|
<li>否则,如果 <code>T</code> 是引用类型,那么就列表初始化一个被引用类型<span class="t-rev-inl t-since-cxx20"><span>或其对应的已知边界数组类型</span> <span><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></span></span>的临时量,并将引用绑定到该临时量。(如果引用是非 const 左值引用则失败)</li>
|
|
</ul>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-since-cxx20">
|
|
<td>
|
|
<dl>
|
|
<dd>如果被引用类型是未知边界数组类型 <span class="t-c"><span class="mw-geshi cpp source-cpp">U<span class="br0">[</span><span class="br0">]</span></span></span> ,那么临时量的类型是 <span class="t-c"><span class="mw-geshi cpp source-cpp">U<span class="br0">[</span>N<span class="br0">]</span></span></span> ,如同它定义为 <span class="t-c"><span class="mw-geshi cpp source-cpp">U temp<span class="br0">[</span><span class="br0">]</span><span class="coMULTI">/*初始化器列表*/</span><span class="sy4">;</span></span></span> ,其中 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="coMULTI">/*初始化器列表*/</span></span></span> 是 <span class="t-spar">花括号初始化器列表</span>。</dd>
|
|
</dl>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<ul>
|
|
<li>否则,如果 <span class="t-spar">花括号初始化器列表</span> 没有任何元素,那么<a href="cpp-language-value_initialization.html">值初始化</a> <code>T</code>。</li>
|
|
</ul>
|
|
<h3><span class="mw-headline" id=".E7.AA.84.E5.8C.96.E8.BD.AC.E6.8D.A2">窄化转换</span></h3>
|
|
<p>列表初始化通过禁止下列转换对<a href="cpp-language-implicit_conversion.html">隐式转换</a>加以限制:</p>
|
|
<ul>
|
|
<li>从浮点类型到整数类型的转换</li>
|
|
</ul>
|
|
<ul>
|
|
<li>从 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">long</span> <span class="kw4">double</span></span></span> 到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">double</span></span></span> 或 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">float</span></span></span> 的转换,以及从 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">double</span></span></span> 到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">float</span></span></span> 的转换,除非来源是<a href="cpp-language-constant_expression.html">常量表达式</a>且不发生溢出</li>
|
|
</ul>
|
|
<ul>
|
|
<li>从整数类型到浮点类型的转换,除非来源是其值能完全存储于目标类型的常量表达式</li>
|
|
</ul>
|
|
<ul>
|
|
<li>从整数或无作用域枚举类型到不能表示原类型所有值的整数类型的转换,除非来源是其值能完全存储于目标类型的常量表达式</li>
|
|
</ul>
|
|
<ul>
|
|
<li>从指针或成员指针类型到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 的转换</li>
|
|
</ul>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>每个初始化器子句均<a href="cpp-language-eval_order.html">按顺序早于</a> <span class="t-spar">花括号初始化器列表</span> 中后随于它的任何初始化器子句。这与<a href="cpp-language-operator_other.html#.E5.86.85.E5.BB.BA.E7.9A.84.E5.87.BD.E6.95.B0.E8.B0.83.E7.94.A8.E8.BF.90.E7.AE.97.E7.AC.A6">函数调用表达式</a>相反,它是<span class="t-rev-inl t-until-cxx17"><span><a href="cpp-language-eval_order.html">无顺序的</a></span> <span><span class="t-mark-rev t-until-cxx17">(C++17 前)</span></span></span><span class="t-rev-inl t-since-cxx17"><span><a href="cpp-language-eval_order.html">不确定顺序的</a></span> <span><span class="t-mark-rev t-since-cxx17">(C++17 起)</span></span></span>。</p>
|
|
<p><span class="t-spar">花括号初始化器列表</span> 不是表达式,因此它没有类型,即 <span class="t-c"><span class="mw-geshi cpp source-cpp">decltype<span class="br0">(</span><span class="br0">{</span><span class="nu0">1</span>,<span class="nu0">2</span><span class="br0">}</span><span class="br0">)</span></span></span> 非良构。没有类型意味着模板类型推导无法推导出与 <span class="t-spar">花括号初始化器列表</span> 相匹配的类型,因此给定声明 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw1">template</span><span class="sy1"><</span><span class="kw1">class</span> T<span class="sy1">></span> <span class="kw4">void</span> f<span class="br0">(</span>T<span class="br0">)</span><span class="sy4">;</span></span></span> 则表达式 <span class="t-lc">f({1,2,3})</span> 非良构。然而,模板形参可以另行推导,如 <span class="t-c"><span class="mw-geshi cpp source-cpp"><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="br0">(</span><a href="cpp-iterator-istream_iterator.html"><span class="kw668">std::<span class="me2">istream_iterator</span></span></a><span class="sy1"><</span><span class="kw4">int</span><span class="sy1">></span><span class="br0">(</span><a href="cpp-io-cin.html"><span class="kw1756">std::<span class="me2">cin</span></span></a><span class="br0">)</span>, <span class="br0">{</span><span class="br0">}</span><span class="br0">)</span></span></span> 的情况,其中迭代器类型从首个实参推导,但也被用于第二形参位置。对于<a href="cpp-language-template_argument_deduction.html#.E5.85.B6.E4.BB.96.E8.AF.AD.E5.A2.83">使用关键词 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">auto</span></span></span> 的类型推导</a>中有一个例外,在复制列表初始化中将任何 <span class="t-spar">花括号初始化器列表</span> 均推导为 <span class="t-lc"><a href="cpp-utility-initializer_list.html">std::initializer_list</a></span>。</p>
|
|
<p>同样因为 <span class="t-spar">花括号初始化器列表</span> 没有类型,所以在将它用作重载函数调用的实参时,适用<a href="cpp-language-overload_resolution.html#.E5.88.97.E8.A1.A8.E5.88.9D.E5.A7.8B.E5.8C.96.E9.87.8C.E7.9A.84.E9.9A.90.E5.BC.8F.E8.BD.AC.E6.8D.A2.E5.BA.8F.E5.88.97">重载决议的特殊规则</a>。聚合体直接从同类型的单元素 <span class="t-spar">花括号初始化器列表</span> 进行复制/移动初始化,但非聚合体首先考虑 initializer_list 构造函数:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> X <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 聚合体</span>
|
|
|
|
<span class="kw1">struct</span> Q <span class="br0">{</span>
|
|
Q<span class="br0">(</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
|
|
Q<span class="br0">(</span>Q <span class="kw4">const</span><span class="sy3">&</span><span class="br0">)</span> <span class="sy1">=</span> <span class="kw1">default</span><span class="sy4">;</span>
|
|
Q<span class="br0">(</span><a href="cpp-utility-initializer_list.html"><span class="kw960">std::<span class="me2">initializer_list</span></span></a><span class="sy1"><</span>Q<span class="sy1">></span><span class="br0">)</span> <span class="br0">{</span><span class="br0">}</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span> <span class="br0">{</span> <span class="co1">// 非聚合体</span>
|
|
X x<span class="sy4">;</span>
|
|
X x2 <span class="sy1">=</span> X <span class="br0">{</span> x <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 复制构造函数(非聚合初始化)</span>
|
|
Q q<span class="sy4">;</span>
|
|
Q q2 <span class="sy1">=</span> Q <span class="br0">{</span> q <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 初始化器列表构造函数(非复制构造函数)</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>有些编译器(例如 gcc 10)仅在 C++20 模式认为从指针或成员指针到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 的转换为窄化。</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="co2">#include <map></span>
|
|
<span class="co2">#include <string></span>
|
|
|
|
<span class="kw1">struct</span> Foo <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> mem <span class="sy1">=</span> <span class="br0">{</span><span class="nu0">1</span>,<span class="nu0">2</span>,<span class="nu0">3</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 非静态成员的列表初始化</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> mem2<span class="sy4">;</span>
|
|
Foo<span class="br0">(</span><span class="br0">)</span> <span class="sy4">:</span> mem2<span class="br0">{</span><span class="sy2">-</span><span class="nu0">1</span>, <span class="sy2">-</span><span class="nu0">2</span>, <span class="sy2">-</span><span class="nu0">3</span><span class="br0">}</span> <span class="br0">{</span><span class="br0">}</span> <span class="co1">// 构造函数中的成员列表初始化</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<a href="cpp-utility-pair.html"><span class="kw1096">std::<span class="me2">pair</span></span></a><span class="sy1"><</span><a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a>, <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy1">></span> f<span class="br0">(</span><a href="cpp-utility-pair.html"><span class="kw1096">std::<span class="me2">pair</span></span></a><span class="sy1"><</span><a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a>, <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="sy1">></span> p<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw1">return</span> <span class="br0">{</span>p.<span class="me1">second</span>, p.<span class="me1">first</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// return 语句中的列表初始化</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> n0<span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 值初始化(为零)</span>
|
|
<span class="kw4">int</span> n1<span class="br0">{</span><span class="nu0">1</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 直接列表初始化</span>
|
|
<a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a> s1<span class="br0">{</span><span class="st0">'a'</span>, <span class="st0">'b'</span>, <span class="st0">'c'</span>, <span class="st0">'d'</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// initializer_list 构造函数调用</span>
|
|
<a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a> s2<span class="br0">{</span>s1, <span class="nu0">2</span>, <span class="nu0">2</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 常规构造函数调用</span>
|
|
<a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a> s3<span class="br0">{</span><span class="nu12">0x61</span>, <span class="st0">'a'</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// initializer_list 构造函数偏好 (int, char)</span>
|
|
|
|
<span class="kw4">int</span> n2 <span class="sy1">=</span> <span class="br0">{</span><span class="nu0">1</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 复制列表初始化</span>
|
|
<span class="kw4">double</span> d <span class="sy1">=</span> <span class="kw4">double</span><span class="br0">{</span><span class="nu16">1.2</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 纯右值的列表初始化,然后复制初始化</span>
|
|
<span class="kw4">auto</span> s4 <span class="sy1">=</span> <a href="cpp-string-basic_string.html"><span class="kw1230">std::<span class="me2">string</span></span></a><span class="br0">{</span><span class="st0">"HelloWorld"</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 同上, C++17 起不创建临时对象</span>
|
|
|
|
<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="sy1">=</span> <span class="br0">{</span> <span class="co1">// 嵌套列表初始化</span>
|
|
<span class="br0">{</span><span class="nu0">1</span>, <span class="st0">"a"</span><span class="br0">}</span>,
|
|
<span class="br0">{</span><span class="nu0">2</span>, <span class="br0">{</span><span class="st0">'a'</span>, <span class="st0">'b'</span>, <span class="st0">'c'</span><span class="br0">}</span> <span class="br0">}</span>,
|
|
<span class="br0">{</span><span class="nu0">3</span>, s1<span class="br0">}</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> f<span class="br0">(</span><span class="br0">{</span><span class="st0">"hello"</span>, <span class="st0">"world"</span><span class="br0">}</span><span class="br0">)</span>.<span class="me1">first</span> <span class="co1">// 函数调用中的列表初始化</span>
|
|
<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">int</span> <span class="br0">(</span><span class="sy3">&</span>ar<span class="br0">)</span><span class="br0">[</span><span class="nu0">2</span><span class="br0">]</span> <span class="sy1">=</span> <span class="br0">{</span><span class="nu0">1</span>,<span class="nu0">2</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 绑定左值引用到临时数组</span>
|
|
<span class="kw4">int</span><span class="sy3">&&</span> r1 <span class="sy1">=</span> <span class="br0">{</span><span class="nu0">1</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 绑定右值引用到临时 int</span>
|
|
<span class="co1">// int& r2 = {2}; // 错误:不能绑定右值到非 const 左值引用</span>
|
|
|
|
<span class="co1">// int bad{1.0}; // 错误:窄化转换</span>
|
|
<span class="kw4">unsigned</span> <span class="kw4">char</span> uc1<span class="br0">{</span><span class="nu0">10</span><span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 可以</span>
|
|
<span class="co1">// unsigned char uc2{-1}; // 错误:窄化转换</span>
|
|
|
|
Foo f<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> n0 <span class="sy1"><<</span> <span class="st0">' '</span> <span class="sy1"><<</span> n1 <span class="sy1"><<</span> <span class="st0">' '</span> <span class="sy1"><<</span> n2 <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> s1 <span class="sy1"><<</span> <span class="st0">' '</span> <span class="sy1"><<</span> s2 <span class="sy1"><<</span> <span class="st0">' '</span> <span class="sy1"><<</span> s3 <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> p<span class="sy4">:</span> m<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> p.<span class="me1">first</span> <span class="sy1"><<</span> <span class="st0">' '</span> <span class="sy1"><<</span> p.<span class="me1">second</span> <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="sy4">:</span> f.<span class="me1">mem</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> n <span class="sy1"><<</span> <span class="st0">' '</span><span class="sy4">;</span>
|
|
<span class="kw1">for</span><span class="br0">(</span><span class="kw4">auto</span> n<span class="sy4">:</span> f.<span class="me1">mem2</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> n <span class="sy1"><<</span> <span class="st0">' '</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">world
|
|
0 1 1
|
|
abcd cd aa
|
|
1 a
|
|
2 abc
|
|
3 abcd
|
|
1 2 3 -1 -2 -3</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.cmeerw.net/cwg/issue1301">CWG 1301</a></td>
|
|
<td>C++11</td>
|
|
<td>对源自 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">{</span><span class="br0">}</span></span></span> 的初始化首先考虑值初始化</td>
|
|
<td>首先考虑聚合初始化</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue1467">CWG 1467</a></td>
|
|
<td>C++11</td>
|
|
<td>禁止同类型的聚合体和字符数组初始化;<br />
|
|
单元素列表的 initializer_list 构造函数优先级高于复制构造函数</td>
|
|
<td>允许同类型初始化;<br />
|
|
单元素列表直接初始化</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue2137">CWG 2137</a></td>
|
|
<td>C++11</td>
|
|
<td>initializer_list 构造函数在从 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="br0">{</span>X<span class="br0">}</span></span></span> 初始化时失去复制构造函数的优先级</td>
|
|
<td>非聚合体首先考虑 initializer_list</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.cmeerw.net/cwg/issue2374">CWG 2374</a></td>
|
|
<td>C++17</td>
|
|
<td>枚举的直接列表初始化允许了过多的源类型</td>
|
|
<td>已限制</td>
|
|
</tr>
|
|
<tr>
|
|
<td><a rel="nofollow" class="external text" href="https://wg21.link/P1957R2">P1957R2</a></td>
|
|
<td>C++11</td>
|
|
<td>从指针/成员指针到 <span class="t-c"><span class="mw-geshi cpp source-cpp"><span class="kw4">bool</span></span></span> 的转换不是窄化</td>
|
|
<td>使之为窄化</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<ul>
|
|
<li><a href="cpp-language-constructor.html">构造函数</a></li>
|
|
<li><a href="cpp-language-converting_constructor.html">转换构造函数</a></li>
|
|
<li><a href="cpp-language-copy_assignment.html">复制赋值</a></li>
|
|
<li><a href="cpp-language-copy_constructor.html">复制构造函数</a></li>
|
|
<li><a href="cpp-language-copy_elision.html">复制消除</a></li>
|
|
<li><a href="cpp-language-default_constructor.html">默认构造函数</a></li>
|
|
<li><a href="cpp-language-explicit.html">explicit</a></li>
|
|
<li><a href="cpp-language-initialization.html">初始化</a>
|
|
<ul>
|
|
<li><a href="cpp-language-aggregate_initialization.html">聚合初始化</a></li>
|
|
<li><a href="cpp-language-constant_initialization.html">常量初始化</a></li>
|
|
<li><a href="cpp-language-copy_initialization.html">复制初始化</a></li>
|
|
<li><a href="cpp-language-direct_initialization.html">直接初始化</a></li>
|
|
<li><a href="cpp-language-reference_initialization.html">引用初始化</a></li>
|
|
<li><a href="cpp-language-value_initialization.html">值初始化</a></li>
|
|
<li><a href="cpp-language-zero_initialization.html">零初始化</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="cpp-language-move_assignment.html">移动赋值</a></li>
|
|
<li><a href="cpp-language-move_constructor.html">移动构造函数</a></li>
|
|
<li><a href="cpp-language-new.html">new</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|