Topic: Is `std::exchange(obj, {})` common enough to be


Author: Marc Mutz <marc.mutz@kdab.com>
Date: Fri, 15 Dec 2017 23:10:34 +0100
Raw View
Hi,

many examples using std::exchange pass a default-constructed object as
the second argument:

    for (auto &item : std::exchange(m_items, {}))

    delete std::exchange(m_pImpl, {});

    Object(Object &&other) : m_var(std::exchange(other.m_var, {})) {}

The exchange-with-{} operation would also supplement std::move, which
doesn't actually move. The new function always reliably moves (because
it returns by value).

The question is what name to give to that operation? Some ideas (in
alphabetical order):

- extract (like in node-based containers)
- move_and_reset
- move_and_empty
- reset_move
- take

What do people think?

Thanks,
Marc

--
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/2a6172b11842a358c70a09f1ebc4c658%40kdab.com.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 15 Dec 2017 15:19:47 -0800 (PST)
Raw View
------=_Part_1324_380484032.1513379987139
Content-Type: multipart/alternative;
 boundary="----=_Part_1325_1561696493.1513379987139"

------=_Part_1325_1561696493.1513379987139
Content-Type: text/plain; charset="UTF-8"

On Friday, December 15, 2017 at 5:14:08 PM UTC-5, Marc Mutz wrote:
>
> Hi,
>
> many examples using std::exchange pass a default-constructed object as
> the second argument:
>
>     for (auto &item : std::exchange(m_items, {}))
>
>     delete std::exchange(m_pImpl, {});
>
>     Object(Object &&other) : m_var(std::exchange(other.m_var, {})) {}

The exchange-with-{} operation would also supplement std::move, which
> doesn't actually move. The new function always reliably moves (because
> it returns by value).
>
> The question is what name to give to that operation?


No, the first question is whether we want people to do this.

I can understand why someone might use this idiom when deleting pointers.
But the rest open up too many possibilities for inefficiencies.

Consider this (in tandem with P0408, which adds move support to string
streams):

istringstream stream(std::move(some_string));

The `std::move` is just a cast; the actual move happens within `stream`'s
constructor. By contrast, if you did you "move to prvalue" thing, that
would perform two moves. It first must move to the prvalue, which manifests
a temporary used as the constructor parameter. Then the constructor moves
from that into the stream.

I don't mind people using this kind of `exchange` idiom. But if we have a
function specifically for this, then we are effectively encouraging people
to do it. Even when it's not a good idea.

Also, remember that `exchange` does two things. It moves from the original,
but it also move* into* the original. In the first case, you don't care
that `m_items` gets default initialized; you just want it to be moved-from.
In the other two cases, default initialization is not merely a default;
it's a fundamental part of the algorithm.

So you would need two functions: one that will move a default-constructed
prvalue into the old object (and thus impose both DefaultConstructible and
MoveAssignable requirements on it) and one which does not.

--
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/503d2f75-d34a-41cc-aeaa-d94c34e8e7b3%40isocpp.org.

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

<div dir=3D"ltr">On Friday, December 15, 2017 at 5:14:08 PM UTC-5, Marc Mut=
z wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi,
<br>
<br>many examples using std::exchange pass a default-constructed object as=
=20
<br>the second argument:
<br>
<br>=C2=A0 =C2=A0 for (auto &amp;item : std::exchange(m_items, {}))
<br>
<br>=C2=A0 =C2=A0 delete std::exchange(m_pImpl, {});
<br>
<br>=C2=A0 =C2=A0 Object(Object &amp;&amp;other) : m_var(std::exchange(othe=
r.m_<wbr>var, {})) {}</blockquote><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">The exchange-with-{} operation would also supplement std::move, which=
=20
<br>doesn&#39;t actually move. The new function always reliably moves (beca=
use=20
<br>it returns by value).
<br>
<br>The question is what name to give to that operation?</blockquote><div><=
br></div><div>No, the first question is whether we want people to do this.<=
/div><div><br></div><div>I can understand why someone might use this idiom =
when deleting pointers. But the rest open up too many possibilities for ine=
fficiencies.</div><div><br></div><div>Consider this (in tandem with P0408, =
which adds move support to string streams):</div><div><br></div><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: =
break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettypri=
nt"><div class=3D"subprettyprint"><span class=3D"styled-by-prettify" style=
=3D"color: #000;">istringstream stream</span><span class=3D"styled-by-prett=
ify" style=3D"color: #660;">(</span><span class=3D"styled-by-prettify" styl=
e=3D"color: #000;">std</span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">::</span><span class=3D"styled-by-prettify" style=3D"color: #00=
0;">move</span><span class=3D"styled-by-prettify" style=3D"color: #660;">(<=
/span><span class=3D"styled-by-prettify" style=3D"color: #000;">some_string=
</span><span class=3D"styled-by-prettify" style=3D"color: #660;">));</span>=
<span class=3D"styled-by-prettify" style=3D"color: #000;"><br></span></div>=
</code></div><div><br></div><div>The `std::move` is just a cast; the actual=
 move happens within `stream`&#39;s constructor. By contrast, if you did yo=
u &quot;move to prvalue&quot; thing, that would perform two moves. It first=
 must move to the prvalue, which manifests a temporary used as the construc=
tor parameter. Then the constructor moves from that into the stream.</div><=
div><br></div><div>I don&#39;t mind people using this kind of `exchange` id=
iom. But if we have a function specifically for this, then we are effective=
ly encouraging people to do it. Even when it&#39;s not a good idea.</div><d=
iv><br></div><div>Also, remember that `exchange` does two things. It moves =
from the original, but it also move<i> into</i> the original. In the first =
case, you don&#39;t care that `m_items` gets default initialized; you just =
want it to be moved-from. In the other two cases, default initialization is=
 not merely a default; it&#39;s a fundamental part of the algorithm.</div><=
div><br></div><div>So you would need two functions: one that will move a de=
fault-constructed prvalue into the old object (and thus impose both Default=
Constructible and MoveAssignable requirements on it) and one which does not=
..</div><div><br></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/503d2f75-d34a-41cc-aeaa-d94c34e8e7b3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/503d2f75-d34a-41cc-aeaa-d94c34e8e7b3=
%40isocpp.org</a>.<br />

------=_Part_1325_1561696493.1513379987139--

------=_Part_1324_380484032.1513379987139--

.