Topic: resize_emplace


Author: mihailnajdenov@gmail.com
Date: Sun, 8 Apr 2018 07:40:35 -0700 (PDT)
Raw View
------=_Part_18332_370585096.1523198435130
Content-Type: multipart/alternative;
 boundary="----=_Part_18333_2115295727.1523198435131"

------=_Part_18333_2115295727.1523198435131
Content-Type: text/plain; charset="UTF-8"

Hello,

While writhing a code in the lines of

// (just for illustration)

_blocks.resize(count);

for(auto& b : _blocks)
{
  b.onIsCheckedChanged([this, &b](bool){ showSubmenuForBlock(&b); });
  b.setHeight(height());
  ...
}

I felt the urge to remove the loop and use a ctor instead, as all params
were available upon construction.

But it turns out, it is not that easy.

The problem is that the blocks instances construct objects, which depend on
the pointer to their containing object.

Consider alternative example, a block ctor which creates a child with some
arguments:

Block(args)
 : _child(new Child(this, args))

Granted, these objects do not have value-semantics, but that does not make
them less useful or less likely to be written.

And even if they are made value-like, copying will be expensive (and hard
to implement), hence using them with resize(count, value) will be a bad
idea.


The solution is to have resize_emplace(count, args)

Writing this is fairly straightforward, something like:

// if count > size()

reserve(count);

for(auto i = size(); i < count; ++i)
{
  emplace(cbegin() + i, std::forward<Args...>(args));
}

Needless to say expensive to copy objects can now be resize-constructed as
well.

I also want to point out an interesting sematic difference with resize().

Where resize() fills the container with *identical* objects, resize_emplace
have the potential to create *different* objects, as the same arguments
*could* create different objects
either by using information from the object instance itself, like the this
pointer, or by mutating the argument state b/w calls.

Thanks for Your time!
MN


--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ba788159-e3cf-4de6-9758-78b9ec885172%40isocpp.org.

------=_Part_18333_2115295727.1523198435131
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hello,</div><div><br></div><div>While writhing a code=
 in the lines of=C2=A0<br></div><div><br></div><div><font face=3D"courier n=
ew,monospace">//=C2=A0<span style=3D"text-align: left; color: rgb(34, 34, 3=
4); text-transform: none; text-indent: 0px; letter-spacing: normal; font-si=
ze: 13px; font-style: normal; font-variant: normal; font-weight: 400; text-=
decoration: none; word-spacing: 0px; display: inline !important; white-spac=
e: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgro=
und-color: transparent;">(just for illustration)</span></font></div><div><b=
></b><i></i><u></u><sub></sub><sup></sup><strike></strike><font face=3D"cou=
rier new,monospace"></font><br></div><div><font face=3D"courier new,monospa=
ce">_blocks.resize(count);=C2=A0</font></div><div><font face=3D"courier new=
,monospace"><br> for(auto&amp; b : _blocks)<br> {<br>=C2=A0 b.onIsCheckedCh=
anged([this, &amp;b](bool){ showSubmenuForBlock(&amp;b); });<br>=C2=A0 b.se=
tHeight(height());<br>=C2=A0 ...<br> }</font><br></div><div><font face=3D"c=
ourier new,monospace"><br></font></div><div><font face=3D"arial,sans-serif"=
>I felt the urge to remove the loop and use a ctor instead, as all params w=
ere available upon construction.</font></div><div><br></div><div><font face=
=3D"arial,sans-serif">But it turns out, it is not that easy.</font></div><d=
iv><font face=3D"arial,sans-serif"><br></font></div><div><font face=3D"aria=
l,sans-serif">The problem is that the blocks instances construct objects, w=
hich depend on the pointer to their containing object.</font></div><div><br=
></div><div>Consider alternative example, a block ctor which creates a chil=
d with some arguments:</div><div><div style=3D"background-color: transparen=
t; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-=
bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bo=
rder-image-slice: 100%; border-image-source: none; border-image-width: 1; b=
order-left-color: rgb(34, 34, 34); border-left-style: none; border-left-wid=
th: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; bor=
der-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: =
none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &amp;quot=
;Arial&amp;quot;,&amp;quot;Helvetica&amp;quot;,sans-serif; font-size: 13px;=
 font-style: normal; font-variant: normal; font-weight: 400; letter-spacing=
: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-t=
op: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right:=
 0px; padding-top: 0px; text-align: left; text-decoration: none; text-inden=
t: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: =
normal; word-spacing: 0px;"><font face=3D"courier new,monospace"><br></font=
></div><div style=3D"background-color: transparent; border-bottom-color: rg=
b(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-=
image-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bo=
rder-image-source: none; border-image-width: 1; border-left-color: rgb(34, =
34, 34); border-left-style: none; border-left-width: 0px; border-right-colo=
r: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; bord=
er-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0p=
x; color: rgb(34, 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot=
;Helvetica&amp;quot;,sans-serif; font-size: 13px; font-style: normal; font-=
variant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0=
px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; paddi=
ng-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; te=
xt-align: left; text-decoration: none; text-indent: 0px; text-transform: no=
ne; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;=
"><font face=3D"courier new,monospace">Block(<span style=3D"display: inline=
 !important; float: none; background-color: transparent; color: rgb(34, 34,=
 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font=
-size: 13px; font-style: normal; font-variant: normal; font-weight: 400; le=
tter-spacing: normal; orphans: 2; text-align: left; text-decoration: none; =
text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; whi=
te-space: normal; word-spacing: 0px;">args</span>)</font></div><div style=
=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
 34, 34); font-family: &amp;quot;Arial&amp;quot;,&amp;quot;Helvetica&amp;qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-=
stroke-width: 0px; white-space: normal; word-spacing: 0px;"><font face=3D"c=
ourier new,monospace">=C2=A0: _child(new Child(this, <span style=3D"display=
: inline !important; float: none; background-color: transparent; color: rgb=
(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-ser=
if; font-size: 13px; font-style: normal; font-variant: normal; font-weight:=
 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration=
: none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: =
0px; white-space: normal; word-spacing: 0px;">args</span>))</font><font sty=
le=3D"border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bord=
er-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch;=
 border-image-slice: 100%; border-image-source: none; border-image-width: 1=
; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left-=
width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; =
border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-styl=
e: none; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margi=
n-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padd=
ing-right: 0px; padding-top: 0px;"><br style=3D"background: none; margin: 0=
px; padding: 0px; border: 0px rgb(34, 34, 34); border-image: none; height: =
auto; color: rgb(34, 34, 34); overflow: visible; font-size: 13px; overflow-=
x: visible; overflow-y: visible; min-width: 0px;"></font></div></div><div><=
font face=3D"arial,sans-serif"></font><font face=3D"courier new,monospace">=
</font><font face=3D"arial,sans-serif"></font><b></b><i></i><u></u><sub></s=
ub><sup></sup><strike><font face=3D"courier new,monospace"><br></font></str=
ike></div><div><font face=3D"arial,sans-serif">Granted, these objects do no=
t have value-semantics, but that does not make them less useful or less lik=
ely to be written.</font></div><div><br></div><div>And even if they are mad=
e value-like, copying will be expensive (and hard to implement), hence usin=
g them with <font face=3D"courier new,monospace">resize(count, value)</font=
> will be a bad idea.</div><div><br></div><div><br></div><div>The solution =
is to have <font face=3D"courier new,monospace">resize_emplace(count, args)=
</font></div><div><font face=3D"Courier New"><br></font></div><div>Writing =
this <font face=3D"arial,sans-serif">is fairly straightforward, something l=
ike:</font></div><div><font face=3D"courier new,monospace"><br></font></div=
><div><font face=3D"courier new,monospace">// if count &gt; size()<br><br>r=
eserve(count);<br><br> for(auto i =3D size(); i &lt; count; ++i)<br> {<br>=
=C2=A0 emplace(cbegin() + i, std::forward&lt;Args...&gt;(args));<br> }</fon=
t></div><div><font face=3D"Courier New"><br></font></div><div><font face=3D=
"arial,sans-serif">Needless to say expensive to copy objects can now be res=
ize-constructed as well.</font></div><div><font face=3D"arial,sans-serif"><=
br></font></div><div><font face=3D"arial,sans-serif">I also want to point o=
ut an interesting sematic difference with <font face=3D"courier new,monospa=
ce">resize()</font>.=C2=A0 </font></div><div><br></div><div><font face=3D"a=
rial,sans-serif">Where resize() fills the container with <i>identical</i> o=
bjects, resize_emplace have the potential to create <i>different</i> object=
s, as the same arguments <i>could</i> create different objects=C2=A0</font>=
</div><div>either by using information from the object instance itself, lik=
e the <font face=3D"courier new,monospace">this</font> pointer, or by mutat=
ing the argument state b/w calls.</div><div><br></div><div>Thanks for Your =
time!</div><div>MN</div><div><font face=3D"arial,sans-serif"></font><i></i>=
<i></i><br></div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike></=
strike><font face=3D"courier new,monospace"></font><br></div><div><pre styl=
e=3D" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;=
 -qt-block-indent:0; text-indent:0px;"></pre><b></b></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ba788159-e3cf-4de6-9758-78b9ec885172%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ba788159-e3cf-4de6-9758-78b9ec885172=
%40isocpp.org</a>.<br />

------=_Part_18333_2115295727.1523198435131--

------=_Part_18332_370585096.1523198435130--

.