Topic: Emplace and Output Iterators


Author: Justin Bassett <jbassett271@gmail.com>
Date: Wed, 20 Jun 2018 22:51:59 -0700 (PDT)
Raw View
------=_Part_2769_1426299826.1529560319590
Content-Type: multipart/alternative;
 boundary="----=_Part_2770_1597013103.1529560319591"

------=_Part_2770_1597013103.1529560319591
Content-Type: text/plain; charset="UTF-8"

With the standard algorithms, std::inserter, std::back_inserter, and
std::front_inserter let us use output iterators to insert into a container.
However, these call the container's insert-like functions rather than
emplace-like functions. I claim there should be emplace versions of these.
It's strange that using the algorithms forces the user to drop the ability
to use the emplacing functions.

Here's what I'm talking about: https://wandbox.org/permlink/PmNcCvmuWTRHdjir

The idea is for std::*_emplacer's operator= to accept a tuple and call the
container's corresponding emplace_* function. This tuple can't come from
std::make_tuple, std::forward_as_tuple, or std::tie, though. That would
either defeat the purpose of using the emplacing operations, or would be
really easy to make dangling references. Thus, I added an emplace_as_tuple
function to the sample, which is almost the same as forward_as_tuple, but
rvalue references are stripped:

template <typename... Ts>
std::tuple<Ts...> emplace_as_tuple(Ts&&... ts) {
    return {std::forward<Ts>(ts)...};
}

// ...

template <typename Container>
class back_emplace_iterator {
public:
    // ...

    // How an operator= might look, although it should be constrained to
not accept a back_emplace_iterator
    template <typename Tuple>
    back_emplace_iterator& operator=(Tuple&& tuple) {
        std::apply([&](auto&&... args) {

container->emplace_back(std::forward<decltype(args)>(args)...);
            }, std::forward<Tuple>(tuple)
        );

        return *this;
    }

    // ...
};

This would also require adding an emplace overload to the associative
containers to mirror insert; that is, provide an overload that works like
emplace_hint. Alternatively, emplace_hint could be added to the sequence
containers.

--
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/b5a3cfd5-50d9-4a0b-bfa3-a5b23839d9ad%40isocpp.org.

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

<div dir=3D"ltr"><div>With the standard algorithms, <font face=3D"courier n=
ew, monospace">std::inserter</font>,=C2=A0<font face=3D"courier new, monosp=
ace">std::back_inserter</font>, and <font face=3D"courier new, monospace">s=
td::front_inserter</font>=C2=A0let us use output iterators to insert into a=
 container. However, these call the container&#39;s <font face=3D"courier n=
ew, monospace">insert</font>-like functions rather than <font face=3D"couri=
er new, monospace">emplace</font>-like functions. I claim there should be e=
mplace versions of these. It&#39;s strange that using the algorithms forces=
 the user to drop the ability to use the emplacing functions.</div><div><br=
></div><div>Here&#39;s what I&#39;m talking about:=C2=A0<a href=3D"https://=
wandbox.org/permlink/PmNcCvmuWTRHdjir">https://wandbox.org/permlink/PmNcCvm=
uWTRHdjir</a></div><div><br></div><div>The idea is for <font face=3D"courie=
r new, monospace">std::*_emplacer</font><font face=3D"arial, sans-serif">&#=
39;s </font><font face=3D"courier new, monospace">operator=3D</font><font f=
ace=3D"arial, sans-serif"> to accept a tuple and call the container&#39;s c=
orresponding </font><font face=3D"courier new, monospace">emplace_*</font><=
font face=3D"arial, sans-serif"> function. This tuple can&#39;t come from <=
/font><font face=3D"courier new, monospace">std::make_tuple</font><font fac=
e=3D"arial, sans-serif">, </font><font face=3D"courier new, monospace">std:=
:forward_as_tuple</font><font face=3D"arial, sans-serif">, or </font><font =
face=3D"courier new, monospace">std::tie</font><font face=3D"arial, sans-se=
rif">, though. That would either defeat the purpose of using the emplacing =
operations, or would be really easy to make dangling references. Thus, I ad=
ded an </font><font face=3D"courier new, monospace">emplace_as_tuple</font>=
<font face=3D"arial, sans-serif"> function to the sample, which is almost t=
he same as </font><font face=3D"courier new, monospace">forward_as_tuple</f=
ont><font face=3D"arial, sans-serif">, but rvalue references are stripped:<=
/font></div><div><font face=3D"arial, sans-serif"><br></font></div><div><fo=
nt face=3D"arial, sans-serif"><div class=3D"prettyprint" style=3D"backgroun=
d-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style=
: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettypr=
int"><div class=3D"subprettyprint"><div class=3D"subprettyprint">template &=
lt;typename... Ts&gt;</div><div class=3D"subprettyprint">std::tuple&lt;Ts..=
..&gt; emplace_as_tuple(Ts&amp;&amp;... ts) {</div><div class=3D"subprettypr=
int">=C2=A0 =C2=A0 return {std::forward&lt;Ts&gt;(ts)...};</div><div class=
=3D"subprettyprint">}<br><br>// ...<br><br><div class=3D"subprettyprint">te=
mplate &lt;typename Container&gt;</div><div class=3D"subprettyprint">class =
back_emplace_iterator {<br>public:<br>=C2=A0 =C2=A0 // ...<br><br></div>=C2=
=A0 =C2=A0 // How an operator=3D might look, although it should be constrai=
ned to not accept a back_emplace_iterator<br><div class=3D"subprettyprint">=
<div class=3D"subprettyprint">=C2=A0 =C2=A0 template &lt;typename Tuple&gt;=
</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 back_emplace_iterator&amp=
; operator=3D(Tuple&amp;&amp; tuple) {</div><div class=3D"subprettyprint">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::apply([&amp;](auto&amp;&amp;... args) {</d=
iv><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 container-&gt;emplace_back(std::forward&lt;decltype(args)&gt;=
(args)...);</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 }, std::forward&lt;Tuple&gt;(tuple)</div><div class=3D"subpre=
ttyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 );</div><div class=3D"subprettyprint"=
>=C2=A0 =C2=A0=C2=A0</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 return *this;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 }=
<br>=C2=A0 =C2=A0=C2=A0<br>=C2=A0 =C2=A0 // ...<br>};</div></div></div></di=
v></code></div><br>This would also require adding an </font><font face=3D"c=
ourier new, monospace">emplace </font><font face=3D"arial, sans-serif">over=
load to the associative containers to mirror </font><font face=3D"courier n=
ew, monospace">insert</font><font face=3D"arial, sans-serif">; that is, pro=
vide an overload that works like </font><font face=3D"courier new, monospac=
e">emplace_hint</font><font face=3D"arial, sans-serif">. Alternatively, </f=
ont><font face=3D"courier new, monospace">emplace_hint </font><font face=3D=
"arial, sans-serif">could be added to the sequence containers</font><font f=
ace=3D"arial, sans-serif">.</font></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/b5a3cfd5-50d9-4a0b-bfa3-a5b23839d9ad%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b5a3cfd5-50d9-4a0b-bfa3-a5b23839d9ad=
%40isocpp.org</a>.<br />

------=_Part_2770_1597013103.1529560319591--

------=_Part_2769_1426299826.1529560319590--

.


Author: Justin Bassett <jbassett271@gmail.com>
Date: Wed, 20 Jun 2018 23:06:19 -0700
Raw View
--000000000000c51380056f20b6fe
Content-Type: text/plain; charset="UTF-8"

I'm realizing that this emplace_as_tuple is actually also easy to use
incorrectly. Any lvalue references must come from the function arguments or
outside. Using std::make_tuple for the purpose costs an extra move on
lvalue references, with no extra cost for temporaries, but it doesn't have
the problem of being as easy to cause dangling references.

On Wed, Jun 20, 2018 at 10:51 PM, Justin Bassett <jbassett271@gmail.com>
wrote:

> With the standard algorithms, std::inserter, std::back_inserter, and
> std::front_inserter let us use output iterators to insert into a
> container. However, these call the container's insert-like functions
> rather than emplace-like functions. I claim there should be emplace
> versions of these. It's strange that using the algorithms forces the user
> to drop the ability to use the emplacing functions.
>
> Here's what I'm talking about: https://wandbox.org/
> permlink/PmNcCvmuWTRHdjir
>
> The idea is for std::*_emplacer's operator= to accept a tuple and call
> the container's corresponding emplace_* function. This tuple can't come
> from std::make_tuple, std::forward_as_tuple, or std::tie, though. That
> would either defeat the purpose of using the emplacing operations, or would
> be really easy to make dangling references. Thus, I added an
> emplace_as_tuple function to the sample, which is almost the same as
> forward_as_tuple, but rvalue references are stripped:
>
> template <typename... Ts>
> std::tuple<Ts...> emplace_as_tuple(Ts&&... ts) {
>     return {std::forward<Ts>(ts)...};
> }
>
> // ...
>
> template <typename Container>
> class back_emplace_iterator {
> public:
>     // ...
>
>     // How an operator= might look, although it should be constrained to
> not accept a back_emplace_iterator
>     template <typename Tuple>
>     back_emplace_iterator& operator=(Tuple&& tuple) {
>         std::apply([&](auto&&... args) {
>                 container->emplace_back(std::
> forward<decltype(args)>(args)...);
>             }, std::forward<Tuple>(tuple)
>         );
>
>         return *this;
>     }
>
>     // ...
> };
>
> This would also require adding an emplace overload to the associative
> containers to mirror insert; that is, provide an overload that works like
> emplace_hint. Alternatively, emplace_hint could be added to the sequence
> containers.
>
> --
> 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/b5a3cfd5-50d9-4a0b-
> bfa3-a5b23839d9ad%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b5a3cfd5-50d9-4a0b-bfa3-a5b23839d9ad%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

--
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/CAPuuy5eEY7qw5ndA2-vM8xCZUB6TBX4JhemMN9b%2BWyr1avML-w%40mail.gmail.com.

--000000000000c51380056f20b6fe
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I&#39;m realizing that this emplace_as_tuple is actually a=
lso easy to use incorrectly. Any lvalue references must come from the funct=
ion arguments or outside. Using std::make_tuple for the purpose costs an ex=
tra move on lvalue references, with no extra cost for temporaries, but it d=
oesn&#39;t have the problem of being as easy to cause dangling references.<=
/div><div class=3D"gmail_extra"><br><div class=3D"gmail_quote">On Wed, Jun =
20, 2018 at 10:51 PM, Justin Bassett <span dir=3D"ltr">&lt;<a href=3D"mailt=
o:jbassett271@gmail.com" target=3D"_blank">jbassett271@gmail.com</a>&gt;</s=
pan> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>With th=
e standard algorithms, <font face=3D"courier new, monospace">std::inserter<=
/font>,=C2=A0<font face=3D"courier new, monospace">std::back_<wbr>inserter<=
/font>, and <font face=3D"courier new, monospace">std::front_inserter</font=
>=C2=A0let us use output iterators to insert into a container. However, the=
se call the container&#39;s <font face=3D"courier new, monospace">insert</f=
ont>-like functions rather than <font face=3D"courier new, monospace">empla=
ce</font>-like functions. I claim there should be emplace versions of these=
.. It&#39;s strange that using the algorithms forces the user to drop the ab=
ility to use the emplacing functions.</div><div><br></div><div>Here&#39;s w=
hat I&#39;m talking about:=C2=A0<a href=3D"https://wandbox.org/permlink/PmN=
cCvmuWTRHdjir" target=3D"_blank">https://wandbox.org/<wbr>permlink/PmNcCvmu=
WTRHdjir</a></div><div><br></div><div>The idea is for <font face=3D"courier=
 new, monospace">std::*_emplacer</font><font face=3D"arial, sans-serif">&#3=
9;s </font><font face=3D"courier new, monospace">operator=3D</font><font fa=
ce=3D"arial, sans-serif"> to accept a tuple and call the container&#39;s co=
rresponding </font><font face=3D"courier new, monospace">emplace_*</font><f=
ont face=3D"arial, sans-serif"> function. This tuple can&#39;t come from </=
font><font face=3D"courier new, monospace">std::make_tuple</font><font face=
=3D"arial, sans-serif">, </font><font face=3D"courier new, monospace">std::=
forward_as_tuple</font><font face=3D"arial, sans-serif">, or </font><font f=
ace=3D"courier new, monospace">std::tie</font><font face=3D"arial, sans-ser=
if">, though. That would either defeat the purpose of using the emplacing o=
perations, or would be really easy to make dangling references. Thus, I add=
ed an </font><font face=3D"courier new, monospace">emplace_as_tuple</font><=
font face=3D"arial, sans-serif"> function to the sample, which is almost th=
e same as </font><font face=3D"courier new, monospace">forward_as_tuple</fo=
nt><font face=3D"arial, sans-serif">, but rvalue references are stripped:</=
font></div><div><font face=3D"arial, sans-serif"><br></font></div><div><fon=
t face=3D"arial, sans-serif"><div class=3D"m_-6853947461580297700prettyprin=
t" style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187)=
;border-style:solid;border-width:1px;word-wrap:break-word"><code class=3D"m=
_-6853947461580297700prettyprint"><div class=3D"m_-6853947461580297700subpr=
ettyprint"><div class=3D"m_-6853947461580297700subprettyprint">template &lt=
;typename... Ts&gt;</div><div class=3D"m_-6853947461580297700subprettyprint=
">std::tuple&lt;Ts...&gt; emplace_as_tuple(Ts&amp;&amp;... ts) {</div><div =
class=3D"m_-6853947461580297700subprettyprint">=C2=A0 =C2=A0 return {std::f=
orward&lt;Ts&gt;(ts)...};</div><div class=3D"m_-6853947461580297700subprett=
yprint">}<br><br>// ...<br><br><div class=3D"m_-6853947461580297700subprett=
yprint">template &lt;typename Container&gt;</div><div class=3D"m_-685394746=
1580297700subprettyprint">class back_emplace_iterator {<br>public:<br>=C2=
=A0 =C2=A0 // ...<br><br></div>=C2=A0 =C2=A0 // How an operator=3D might lo=
ok, although it should be constrained to not accept a back_emplace_iterator=
<br><div class=3D"m_-6853947461580297700subprettyprint"><div class=3D"m_-68=
53947461580297700subprettyprint">=C2=A0 =C2=A0 template &lt;typename Tuple&=
gt;</div><div class=3D"m_-6853947461580297700subprettyprint">=C2=A0 =C2=A0 =
back_emplace_iterator&amp; operator=3D(Tuple&amp;&amp; tuple) {</div><div c=
lass=3D"m_-6853947461580297700subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 s=
td::apply([&amp;](auto&amp;&amp;... args) {</div><div class=3D"m_-685394746=
1580297700subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 container-&gt;emplace_back(std::<wbr>forward&lt;decltype(args)&gt;(a=
rgs).<wbr>..);</div><div class=3D"m_-6853947461580297700subprettyprint">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }, std::forward&lt;Tuple&gt;(tuple)<=
/div><div class=3D"m_-6853947461580297700subprettyprint">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 );</div><div class=3D"m_-6853947461580297700subprettyprint">=C2=
=A0 =C2=A0=C2=A0</div><div class=3D"m_-6853947461580297700subprettyprint">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return *this;</div><div class=3D"m_-68539474615=
80297700subprettyprint">=C2=A0 =C2=A0 }<br>=C2=A0 =C2=A0=C2=A0<br>=C2=A0 =
=C2=A0 // ...<br>};</div></div></div></div></code></div><br>This would also=
 require adding an </font><font face=3D"courier new, monospace">emplace </f=
ont><font face=3D"arial, sans-serif">overload to the associative containers=
 to mirror </font><font face=3D"courier new, monospace">insert</font><font =
face=3D"arial, sans-serif">; that is, provide an overload that works like <=
/font><font face=3D"courier new, monospace">emplace_hint</font><font face=
=3D"arial, sans-serif">. Alternatively, </font><font face=3D"courier new, m=
onospace">emplace_hint </font><font face=3D"arial, sans-serif">could be add=
ed to the sequence containers</font><font face=3D"arial, sans-serif">.</fon=
t></div></div><span class=3D"HOEnZb"><font color=3D"#888888">

<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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/b5a3cfd5-50d9-4a0b-bfa3-a5b23839d9ad%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/b5a3=
cfd5-50d9-4a0b-<wbr>bfa3-a5b23839d9ad%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><br></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/CAPuuy5eEY7qw5ndA2-vM8xCZUB6TBX4JhemM=
N9b%2BWyr1avML-w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAPuuy5eEY7qw5n=
dA2-vM8xCZUB6TBX4JhemMN9b%2BWyr1avML-w%40mail.gmail.com</a>.<br />

--000000000000c51380056f20b6fe--

.