Topic: maps and move construction


Author: oleg.smolsky@gmail.com
Date: Thu, 6 Jun 2013 11:24:32 -0700 (PDT)
Raw View
------=_Part_2_27935540.1370543072024
Content-Type: multipart/alternative;
 boundary="----=_Part_3_19010555.1370543072024"

------=_Part_3_19010555.1370543072024
Content-Type: text/plain; charset=ISO-8859-1

Hi there, I've just noticed an issue with maps and move construction (gcc
4.6 and 4.8.1). Here is the digest:

    _map.insert(std::make_pair(1, Movable(1)));        // works

    _map.insert({1, Movable(1)});                      // breaks

The second version demands the copy constructor which is deleted. I've
attached the the whole source (26 lines) to the message.

Is gcc missing some move magic from std::map/std::pair? Or is it following
the standard? Can this work in principle?

Thanks!
Oleg.

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.



------=_Part_3_19010555.1370543072024
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi there, I've just noticed an issue with maps and move construction (gcc 4=
..6 and 4.8.1). Here is the digest:<br><br><span style=3D"font-family: couri=
er new,monospace;">&nbsp;&nbsp;&nbsp; _map.insert(std::make_pair(1, Movable=
(1)));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // works<br><br>&nbsp;&nbs=
p;&nbsp; _map.insert({1, Movable(1)});&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp; // breaks</span><br><br>The second version demands the copy =
constructor which is deleted. I've attached the the whole source (26 lines)=
 to the message.<br><br>Is gcc missing some move magic from std::map/std::p=
air? Or is it following the standard? Can this work in principle?<br><br>Th=
anks!<br>Oleg.<tt><br>
    </tt>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_3_19010555.1370543072024--
------=_Part_2_27935540.1370543072024
Content-Type: text/x-c++src; charset=US-ASCII; name=map.cpp
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=map.cpp
X-Attachment-Id: 0f08cc82-a0ab-46b4-8d48-56da43c95e9d
Content-ID: <0f08cc82-a0ab-46b4-8d48-56da43c95e9d>

#include <map>

struct Movable
{
    Movable(int)
    {
    }

    Movable(Movable &&)
    {
    }

    Movable(const Movable &) = delete;
};

std::map<int, Movable> _map;

void test1()
{
    _map.insert(std::make_pair(1, Movable(1)));
}

void test2()
{
    _map.insert({1, Movable(1)});
}

------=_Part_2_27935540.1370543072024--

.


Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@gmail.com>
Date: Fri, 7 Jun 2013 01:16:39 +0200
Raw View
2013/6/6  <oleg.smolsky@gmail.com>:
> Hi there, I've just noticed an issue with maps and move construction (gcc
> 4.6 and 4.8.1). Here is the digest:
>
>     _map.insert(std::make_pair(1, Movable(1)));        // works
>
>     _map.insert({1, Movable(1)});                      // breaks

This is expected not to work, see below why.

> The second version demands the copy constructor which is deleted. I've
> attached the the whole source (26 lines) to the message.
>
> Is gcc missing some move magic from std::map/std::pair?

No.

> Or is it following the standard?

Yes.

> Can this work in principle?

Not as written.

The compiler attempts to deduce to which insert overload the
initializer-list could match. The template overloads won't work (no
deduction possible, unless there would be an initializer_list function
that could match. There is an initializer overload but that doesn't
match with the initializer-list. You would need a different
braced-init list of the form

{{1, Movable(1)}}

for this. But that form would still cause the same problem that cases
the problem here: The selected form is this one:

pair<iterator, bool> insert(const value_type& x);

Deduction succeeds, but now the map attempts to copy from the const
lvalue of value_type, which is

std::pair<const int, Movable>

Of-course copying won't work here because of the Moveable member, so
it does not succeed.

We would need an additional overload

pair<iterator, bool> insert(value_type&& x);

to make it work. We already have this one

template <class P> pair<iterator, bool> insert(P&& x);

but is won't deduce initializer-lists.

In this case, a much simpler solution is to use emplace instead:

_map.emplace(1, Movable(1));

- Daniel

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/?hl=en.



.


Author: oleg.smolsky@gmail.com
Date: Thu, 6 Jun 2013 18:30:24 -0700 (PDT)
Raw View
------=_Part_274_6057850.1370568624591
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable


On Thursday, June 6, 2013 4:16:39 PM UTC-7, Daniel Kr=FCgler wrote:
>
> In this case, a much simpler solution is to use emplace instead:=20
>
> _map.emplace(1, Movable(1));=20
>
> Ah, fascinating. Thank you very much for the thorough explanation, Daniel=
!

Oleg.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



------=_Part_274_6057850.1370568624591
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br>On Thursday, June 6, 2013 4:16:39 PM UTC-7, Daniel Kr=FCgler wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">In this case, a much simpler solut=
ion is to use emplace instead:
<br>
<br>_map.emplace(1, Movable(1));
<br>
<br></blockquote><div>Ah, fascinating. Thank you very much for the thorough=
 explanation, Daniel!<br><br>Oleg.<br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_274_6057850.1370568624591--

.