<html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type"><style type="text/css">ul.lst-kix_luu1aqnp5xd3-0{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-1{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-2{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-3{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-4{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-5{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-6{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-7{list-style-type:none}ul.lst-kix_luu1aqnp5xd3-8{list-style-type:none}.lst-kix_luu1aqnp5xd3-0>li:before{content:"\0025cf  "}.lst-kix_o019ueidqr7g-8>li:before{content:"\0025a0  "}.lst-kix_o019ueidqr7g-7>li:before{content:"\0025cb  "}ul.lst-kix_3wj8lccjahnf-5{list-style-type:none}ul.lst-kix_i6w7co9bjynz-4{list-style-type:none}ul.lst-kix_3wj8lccjahnf-4{list-style-type:none}ul.lst-kix_i6w7co9bjynz-5{list-style-type:none}ul.lst-kix_3wj8lccjahnf-3{list-style-type:none}ul.lst-kix_i6w7co9bjynz-6{list-style-type:none}ul.lst-kix_3wj8lccjahnf-2{list-style-type:none}ul.lst-kix_i6w7co9bjynz-7{list-style-type:none}ul.lst-kix_i6w7co9bjynz-8{list-style-type:none}ul.lst-kix_3wj8lccjahnf-8{list-style-type:none}ul.lst-kix_3wj8lccjahnf-7{list-style-type:none}ul.lst-kix_3wj8lccjahnf-6{list-style-type:none}ul.lst-kix_o019ueidqr7g-4{list-style-type:none}ul.lst-kix_o019ueidqr7g-5{list-style-type:none}ul.lst-kix_o019ueidqr7g-6{list-style-type:none}ul.lst-kix_o019ueidqr7g-7{list-style-type:none}ul.lst-kix_3wj8lccjahnf-1{list-style-type:none}ul.lst-kix_o019ueidqr7g-8{list-style-type:none}ul.lst-kix_3wj8lccjahnf-0{list-style-type:none}ul.lst-kix_o019ueidqr7g-0{list-style-type:none}ul.lst-kix_o019ueidqr7g-1{list-style-type:none}ul.lst-kix_o019ueidqr7g-2{list-style-type:none}ul.lst-kix_o019ueidqr7g-3{list-style-type:none}.lst-kix_r8w9ia3gom80-3>li:before{content:"\0025cf  "}.lst-kix_3wj8lccjahnf-6>li:before{content:"\0025cf  "}.lst-kix_3wj8lccjahnf-7>li:before{content:"\0025cb  "}.lst-kix_3wj8lccjahnf-5>li:before{content:"\0025a0  "}.lst-kix_r8w9ia3gom80-2>li:before{content:"\0025a0  "}.lst-kix_r8w9ia3gom80-6>li:before{content:"\0025cf  "}.lst-kix_r8w9ia3gom80-7>li:before{content:"\0025cb  "}.lst-kix_r8w9ia3gom80-1>li:before{content:"\0025cb  "}.lst-kix_3wj8lccjahnf-0>li:before{content:"\0025cf  "}.lst-kix_3wj8lccjahnf-8>li:before{content:"\0025a0  "}.lst-kix_r8w9ia3gom80-0>li:before{content:"\0025cf  "}.lst-kix_r8w9ia3gom80-8>li:before{content:"\0025a0  "}ul.lst-kix_i6w7co9bjynz-0{list-style-type:none}ul.lst-kix_i6w7co9bjynz-1{list-style-type:none}ul.lst-kix_i6w7co9bjynz-2{list-style-type:none}ul.lst-kix_i6w7co9bjynz-3{list-style-type:none}.lst-kix_i6w7co9bjynz-0>li:before{content:"\0025cf  "}.lst-kix_o019ueidqr7g-4>li:before{content:"\0025cb  "}.lst-kix_o019ueidqr7g-6>li:before{content:"\0025cf  "}.lst-kix_o019ueidqr7g-2>li:before{content:"\0025a0  "}.lst-kix_o019ueidqr7g-5>li:before{content:"\0025a0  "}.lst-kix_i6w7co9bjynz-3>li:before{content:"\0025cf  "}.lst-kix_i6w7co9bjynz-4>li:before{content:"\0025cb  "}.lst-kix_i6w7co9bjynz-6>li:before{content:"\0025cf  "}.lst-kix_o019ueidqr7g-3>li:before{content:"\0025cf  "}.lst-kix_i6w7co9bjynz-5>li:before{content:"\0025a0  "}.lst-kix_luu1aqnp5xd3-6>li:before{content:"\0025cf  "}.lst-kix_luu1aqnp5xd3-5>li:before{content:"\0025a0  "}.lst-kix_3wj8lccjahnf-1>li:before{content:"\0025cb  "}.lst-kix_luu1aqnp5xd3-4>li:before{content:"\0025cb  "}.lst-kix_3wj8lccjahnf-2>li:before{content:"\0025a0  "}.lst-kix_3wj8lccjahnf-3>li:before{content:"\0025cf  "}.lst-kix_o019ueidqr7g-0>li:before{content:"\0025cf  "}.lst-kix_o019ueidqr7g-1>li:before{content:"\0025cb  "}.lst-kix_luu1aqnp5xd3-1>li:before{content:"\0025cb  "}.lst-kix_luu1aqnp5xd3-3>li:before{content:"\0025cf  "}.lst-kix_r8w9ia3gom80-5>li:before{content:"\0025a0  "}.lst-kix_i6w7co9bjynz-2>li:before{content:"\0025a0  "}.lst-kix_3wj8lccjahnf-4>li:before{content:"\0025cb  "}.lst-kix_r8w9ia3gom80-4>li:before{content:"\0025cb  "}.lst-kix_i6w7co9bjynz-1>li:before{content:"\0025cb  "}.lst-kix_luu1aqnp5xd3-2>li:before{content:"\0025a0  "}.lst-kix_i6w7co9bjynz-8>li:before{content:"\0025a0  "}.lst-kix_luu1aqnp5xd3-7>li:before{content:"\0025cb  "}.lst-kix_i6w7co9bjynz-7>li:before{content:"\0025cb  "}.lst-kix_luu1aqnp5xd3-8>li:before{content:"\0025a0  "}.lst-kix_be0qpnf1qxcd-1>li:before{content:"\0025cb  "}.lst-kix_be0qpnf1qxcd-3>li:before{content:"\0025cf  "}.lst-kix_be0qpnf1qxcd-0>li:before{content:"\0025cf  "}.lst-kix_be0qpnf1qxcd-4>li:before{content:"\0025cb  "}ul.lst-kix_r8w9ia3gom80-7{list-style-type:none}ul.lst-kix_r8w9ia3gom80-8{list-style-type:none}.lst-kix_be0qpnf1qxcd-2>li:before{content:"\0025a0  "}ul.lst-kix_r8w9ia3gom80-3{list-style-type:none}ul.lst-kix_be0qpnf1qxcd-6{list-style-type:none}ul.lst-kix_r8w9ia3gom80-4{list-style-type:none}ul.lst-kix_be0qpnf1qxcd-7{list-style-type:none}ul.lst-kix_r8w9ia3gom80-5{list-style-type:none}ul.lst-kix_be0qpnf1qxcd-4{list-style-type:none}ul.lst-kix_r8w9ia3gom80-6{list-style-type:none}ul.lst-kix_be0qpnf1qxcd-5{list-style-type:none}.lst-kix_be0qpnf1qxcd-7>li:before{content:"\0025cb  "}ul.lst-kix_r8w9ia3gom80-0{list-style-type:none}ul.lst-kix_r8w9ia3gom80-1{list-style-type:none}.lst-kix_be0qpnf1qxcd-8>li:before{content:"\0025a0  "}ul.lst-kix_be0qpnf1qxcd-8{list-style-type:none}ul.lst-kix_r8w9ia3gom80-2{list-style-type:none}.lst-kix_be0qpnf1qxcd-5>li:before{content:"\0025a0  "}ul.lst-kix_be0qpnf1qxcd-2{list-style-type:none}ul.lst-kix_be0qpnf1qxcd-3{list-style-type:none}ul.lst-kix_be0qpnf1qxcd-0{list-style-type:none}.lst-kix_be0qpnf1qxcd-6>li:before{content:"\0025cf  "}ul.lst-kix_be0qpnf1qxcd-1{list-style-type:none}ol{margin:0;padding:0}table td,table th{padding:0}.c10{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:26pt;font-family:"Arial";font-style:normal}.c1{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c5{margin-left:36pt;padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c26{color:#434343;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:14pt;font-family:"Arial";font-style:normal}.c7{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left;height:11pt}.c19{margin-left:36pt;padding-top:3pt;padding-bottom:0pt;line-height:1.0;orphans:2;widows:2;text-align:left}.c0{color:#000000;font-weight:400;text-decoration:none;vertical-align:baseline;font-size:20pt;font-family:"Arial";font-style:normal}.c23{padding-top:4pt;padding-bottom:0pt;line-height:1.0;orphans:2;widows:2;text-align:left}.c21{padding-top:10pt;padding-bottom:0pt;line-height:1.0;orphans:2;widows:2;text-align:left}.c24{padding-top:10pt;padding-bottom:4pt;line-height:1.0;orphans:2;widows:2;text-align:left}.c12{padding-top:0pt;padding-bottom:0pt;line-height:1.15;orphans:2;widows:2;text-align:left}.c16{padding-top:0pt;padding-bottom:3pt;line-height:1.15;page-break-after:avoid;text-align:left}.c17{padding-top:20pt;padding-bottom:6pt;line-height:1.15;page-break-after:avoid;text-align:left}.c11{font-weight:400;vertical-align:baseline;font-size:11pt;font-family:"Arial";font-style:normal}.c25{padding-top:16pt;padding-bottom:4pt;line-height:1.15;page-break-after:avoid;text-align:left}.c9{color:#000000;text-decoration:none;vertical-align:baseline;font-size:11pt;font-style:normal}.c14{padding-top:0pt;padding-bottom:0pt;line-height:1.0;text-align:left;height:11pt}.c15{padding-top:0pt;padding-bottom:0pt;line-height:1.0;text-align:left}.c6{text-decoration-skip-ink:none;-webkit-text-decoration-skip:none;color:#1155cc;text-decoration:underline}.c27{background-color:#ffffff;max-width:468pt;padding:72pt 72pt 72pt 72pt}.c13{font-weight:700;font-family:"Courier New"}.c4{color:inherit;text-decoration:inherit}.c2{padding:0;margin:0}.c3{font-weight:400;font-family:"Courier New"}.c18{border:1px solid black;margin:5px}.c20{font-style:italic}.c8{padding-left:0pt}.c22{margin-left:72pt}.title{padding-top:0pt;color:#000000;font-size:26pt;padding-bottom:3pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}.subtitle{padding-top:0pt;color:#666666;font-size:15pt;padding-bottom:16pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}li{color:#000000;font-size:11pt;font-family:"Arial"}p{margin:0;color:#000000;font-size:11pt;font-family:"Arial"}h1{padding-top:20pt;color:#000000;font-size:20pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h2{padding-top:18pt;color:#000000;font-size:16pt;padding-bottom:6pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h3{padding-top:16pt;color:#434343;font-size:14pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h4{padding-top:14pt;color:#666666;font-size:12pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h5{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;orphans:2;widows:2;text-align:left}h6{padding-top:12pt;color:#666666;font-size:11pt;padding-bottom:4pt;font-family:"Arial";line-height:1.15;page-break-after:avoid;font-style:italic;orphans:2;widows:2;text-align:left}</style></head><body class="c27"><p class="c12"><span class="c1">Doc no:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;P1072R0</span></p><p class="c12"><span class="c1">Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2018-05-04</span></p><p class="c12"><span>Reply to:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Chris Kennelly (</span><span class="c6"><a class="c4" href="mailto:ckennelly@google.com">ckennelly@google.com</a></span><span class="c1">), Mark Zeren (mzeren@vmware.com)</span></p><p class="c12"><span class="c1">Audience:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LEWG/LWG/SG16</span></p><p class="c7"><span class="c1"></span></p><p class="c16 title" id="h.6t45t6ppmdn8"><span class="c10">Default Initialization for basic_string</span></p><p class="c7"><span class="c1"></span></p><p class="c23"><span class="c6"><a class="c4" href="#h.ei9trpxk5e">Summary</a></span></p><p class="c21"><span class="c6"><a class="c4" href="#h.q8n9xkh6fvk4">Motivation</a></span></p><p class="c21"><span class="c6"><a class="c4" href="#h.ri74k5iv1s1h">Proposal</a></span></p><p class="c19"><span class="c6"><a class="c4" href="#h.v6ji8f1g0g1">Option A</a></span></p><p class="c19"><span class="c6"><a class="c4" href="#h.nrtalowrnfui">Option B</a></span></p><p class="c24"><span class="c6"><a class="c4" href="#h.9izob31yctm">Related Work</a></span></p><p class="c7"><span class="c1"></span></p><h1 class="c17" id="h.ei9trpxk5e"><span class="c0">Summary</span></h1><p class="c12"><span>Extend </span><span class="c3">basic_string</span><span class="c1">&nbsp;to allow access to default-initialized elements.</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span>We propose similar changes to </span><span class="c3">vector</span><span>&nbsp;in </span><span class="c6"><a class="c4" href="http://wg21.link/P1010R0">P1010R0</a></span><span class="c1">.</span></p><h1 class="c17" id="h.q8n9xkh6fvk4"><span class="c0">Motivation</span></h1><p class="c12"><span>Performance sensitive code is impacted by the cost of manipulating strings: &nbsp;When streaming data into a </span><span class="c3">basic_string</span><span class="c1">, a programmer is forced to choose between extra initialization (resize then copy directly in) or extra copies (copy into a temporary buffer, then append).</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c1">Consider writing a pattern several times into a string:</span></p><p class="c7"><span class="c1"></span></p><p class="c5"><span class="c3 c9">std::string GeneratePattern(const std::string&amp; pattern, size_t count) {</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;std::string ret;</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;ret.reserve(pattern.size() * count);<br> &nbsp; for (size_t i = 0; i &lt; count; i++) {</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp; &nbsp;ret.append(pattern); &nbsp;// BAD: Extra bookkeeping</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;}</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;return ret;</span></p><p class="c5"><span class="c9 c3">}</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c1">Alternatively, we could adjust the output string&rsquo;s size to its final size, avoiding the bookkeeping in append at the cost of extra initialization:<br></span></p><p class="c5"><span class="c9 c3">std::string GeneratePattern(const std::string&amp; pattern, size_t count) {</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;std::string ret;</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;const auto step = pattern.size();</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;ret.size(step * count); &nbsp;// BAD: &nbsp;Extra initialization<br> &nbsp; for (size_t i = 0; i &lt; count; i++) {</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp; &nbsp;// GOOD: No bookkeeping</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp; &nbsp;memcpy(ret.data() + i * step, pattern.data(), step);</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;}</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;return ret;</span></p><p class="c5"><span class="c9 c3">}</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c1">We propose adding an interface to basic_string to avoid this tradeoff:</span></p><p class="c7"><span class="c1"></span></p><p class="c5"><span class="c9 c3">std::string GeneratePattern(const std::string&amp; pattern, size_t count) {</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;std::string ret;</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;const auto step = pattern.size();</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;// GOOD: &nbsp;No initialization</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;ret.resize_uninitialized(step * count);<br> &nbsp; for (size_t i = 0; i &lt; count; i++) {</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp; &nbsp;// GOOD: No bookkeeping</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp; &nbsp;memcpy(ret.data() + i * step, pattern.data(), step);</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;}</span></p><p class="c5"><span class="c9 c3">&nbsp; &nbsp;return ret;</span></p><p class="c5"><span class="c3">}</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span>Google</span><span>&nbsp;has implemented </span><span class="c3">resize_uninitialized</span><span class="c1">&nbsp;(Option A) in its standard library. &nbsp;This is used in performance critical sections of code such as:</span></p><ul class="c2 lst-kix_luu1aqnp5xd3-0 start"><li class="c5 c8"><span class="c6"><a class="c4" href="https://github.com/abseil/abseil-cpp">Abseil</a></span><span>: </span><span class="c6"><a class="c4" href="https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_cat.cc#L96">StrCat</a></span><span>&nbsp;and </span><span class="c6"><a class="c4" href="https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_cat.cc#L192">StrAppend</a></span><span>&nbsp;can copy bytes directly into the final string, eliding size checks that </span><span class="c3">basic_string::append</span><span>&nbsp;would perform when adding each piece. &nbsp;These uses are similar to the examples illustrated in this section.</span></li><li class="c5 c8"><span class="c6"><a class="c4" href="https://github.com/google/protobuf">Protocol Buffers</a></span><span>: &nbsp;Extraneous copies or initialization are avoided where the size is known before the data is available. &nbsp;On </span><span class="c6"><a class="c4" href="https://github.com/google/protobuf/blob/master/src/google/protobuf/message_lite.cc#L293">serialization</a></span><span>, the size has been calculated (needed for length prefixed data) before the contents are ready. &nbsp;On </span><span class="c6"><a class="c4" href="https://github.com/google/protobuf/blob/master/src/google/protobuf/io/coded_stream_inl.h#L55">deserialization</a></span><span>, the size will have been parsed and bytes need to be copied into a string for user code to access.</span></li><li class="c5 c8"><span class="c6"><a class="c4" href="https://github.com/google/snappy">Snappy</a></span><span>: &nbsp;During </span><span class="c6"><a class="c4" href="https://github.com/google/snappy/blob/master/snappy.cc#L1264">decompression</a></span><span>, the final size of the output buffer is known before the contents are ready. &nbsp;During </span><span class="c6"><a class="c4" href="https://github.com/google/snappy/blob/master/snappy.cc#L1324">compression</a></span><span>, an upperbound on the final compressed size is known, allowing data to be efficiently added to the output buffer (eliding </span><span class="c3">append</span><span class="c1">&rsquo;s checks) and the string to be shrunk to its final, correct size.</span></li></ul><p class="c7"><span class="c1"></span></p><p class="c7"><span class="c1"></span></p><h1 class="c17" id="h.ri74k5iv1s1h"><span class="c0">Proposal</span></h1><h3 class="c25" id="h.v6ji8f1g0g1"><span class="c26">Option A</span></h3><p class="c12"><span class="c1">Add to basic.string.capacity [24.3.2.4]:</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c13">void resize_uninitialized(size_type n);</span></p><p class="c7"><span class="c1"></span></p><ul class="c2 lst-kix_r8w9ia3gom80-0 start"><li class="c5 c8"><span class="c20">Throws</span><span>: </span><span class="c3">length_error</span><span>&nbsp;if </span><span class="c9 c3">n &gt; max_size()</span></li><li class="c5 c8"><span class="c20">Effects</span><span>: &nbsp;Alters the length of the string designated by </span><span class="c3">*this</span><span class="c1">&nbsp;as follows:</span></li></ul><ul class="c2 lst-kix_r8w9ia3gom80-1 start"><li class="c12 c8 c22"><span>If </span><span class="c3">n &lt;= size()</span><span>, calls </span><span class="c9 c3">resize(n)</span></li><li class="c12 c8 c22"><span>If </span><span class="c3">n &gt; size()</span><span>, the function replaces the string designated by </span><span class="c3">*this</span><span>&nbsp;with a string of length </span><span class="c3">n</span><span>&nbsp;whose first </span><span class="c3">size()</span><span>&nbsp;elements are a copy of the original string designated by </span><span class="c3">*this</span><span class="c1">, and whose remaining elements are default initialized.</span></li></ul><p class="c7"><span class="c1"></span></p><p class="c12"><span>The &ldquo;null terminator&rdquo; invariant of </span><span class="c3">basic_string</span><span>&nbsp;[24.3.2] is unchanged.</span></p><h3 class="c25" id="h.bj2lykexpxk"><span class="c26">Option B</span></h3><p class="c12"><span>While there is implementation experience for Option A, Option B may be more friendly to processor memory prefetchers on modern architectures, particularly when memory is being initialized from </span><span class="c3">uninitialized_data()</span><span>&nbsp;in order for long strings.</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c1">Add to string.accessors [24.3.2.7.1]</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c9 c13">charT* uninitialized_data() noexcept;</span></p><p class="c7"><span class="c1"></span></p><ul class="c2 lst-kix_be0qpnf1qxcd-0 start"><li class="c5 c8"><span>Returns a pointer </span><span class="c3">p</span><span>&nbsp;such that </span><span class="c3">p == data() + size()</span><span>&nbsp;and </span><span class="c3">[p, p + capacity() - size())</span><span>&nbsp;is a valid range. &nbsp;All values except </span><span class="c3">*p</span><span>&nbsp;have indeterminate value. &nbsp;Modifying </span><span class="c3">*p</span><span>&nbsp;requires a subsequent call to </span><span class="c3">insert_from_capacity()</span><span class="c1">&nbsp;to restore the &ldquo;null terminator.&rdquo;</span></li><li class="c5 c8"><span class="c1">Complexity: Constant time</span></li></ul><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c1">Add:</span></p><p class="c7"><span class="c1"></span></p><p class="c12"><span class="c9 c13">basic_string& insert_from_capacity(size_type n);</span></p><p class="c7"><span class="c1"></span></p><ul class="c2 lst-kix_3wj8lccjahnf-0 start"><li class="c5 c8"><span>Throws: </span><span class="c3">length_error</span><span>&nbsp;if </span><span class="c9 c3">n &gt; capacity() - size()</span></li><li class="c5 c8"><span>Effects: &nbsp;Appends </span><span class="c3">n</span><span>&nbsp;elements that must have been previously initialized by the application via </span><span class="c3">uninitialized_data()</span><span>. &nbsp;</span><span class="c3">data() + size()</span><span>&nbsp;points to an object with value</span><span class="c3">&nbsp;charT()</span><span class="c1">.</span></li></ul><h1 class="c17" id="h.9izob31yctm"><span class="c0">Related Work</span></h1><ul class="c2 lst-kix_i6w7co9bjynz-0 start"><li class="c5 c8"><span class="c6"><a class="c4" href="https://wg21.link/P0593">P0593</a></span><span>: &nbsp;Bless implicit creation of trivial types</span></li><li class="c5 c8"><span class="c6"><a class="c4" href="https://wg21.link/P1010R0">P1010</a></span><span class="c1">: &nbsp;Proposal to expose default-initialized elements for vector</span></li></ul></body></html>