Prev: lambdas and non-captured, unevaluated operands
Next: C++0x support in compilers for embedded systems
From: Brendan on 25 Apr 2010 17:52 I'm trying to use a type that is moveable, but not copyable, in a standard container, in this case an unordered_map. When I try to insert it, I get complaints about a deleted copy constructor. I thought that move only objects were supported in standard containers? Here's my type: struct session_t { session_t() : fd(make_unique_fd(0)) {} session_t(const session_t&) = delete; session_t& operator=(const session_t&) = delete; session_t(session_t&& session) : fd(move(session.fd)) {} session_t& operator=(session_t&& other) { if (this != &other) { fd = move(other.fd); } return *this; } unique_fd fd; }; typedef unordered_map<int, session_t> session_map; Heres where the error pops up: map.insert(make_pair(*session.fd, move(session))); Testing on GCC 4.4 -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 26 Apr 2010 01:50 On 26 Apr., 10:52, Brendan <catph...(a)catphive.net> wrote: > I'm trying to use a type that is moveable, but not copyable, in a > standard container, in this case an unordered_map. When I try to > insert it, I get complaints about a deleted copy constructor. I > thought that move only objects were supported in standard containers? > > Here's my type: > > struct session_t { > session_t() : fd(make_unique_fd(0)) {} > session_t(const session_t&) = delete; > session_t& operator=(const session_t&) = delete; > session_t(session_t&& session) : fd(move(session.fd)) {} > session_t& operator=(session_t&& other) { > if (this != &other) { > fd = move(other.fd); > } > return *this; > } > > unique_fd fd; > }; > > typedef unordered_map<int, session_t> session_map; > > Heres where the error pops up: > map.insert(make_pair(*session.fd, move(session))); This should work. It should also work more directly by writing map.emplace(*session.fd, std::move(session)); instead. > Testing on GCC 4.4 Even the most recent 4.5.0-1 trunk of gcc does not properly handle this and does not recognize the emplace member function. Same problem for std::map. Looks like an incomplete implementation to me in regard to the working draft. HTH & Greetings from Bremen, Daniel Kr�gler -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Howard Hinnant on 26 Apr 2010 09:10 On Apr 26, 4:52 am, Brendan <catph...(a)catphive.net> wrote: > I'm trying to use a type that is moveable, but not copyable, in a > standard container, in this case an unordered_map. When I try to > insert it, I get complaints about a deleted copy constructor. I > thought that move only objects were supported in standard containers? > > Here's my type: > > struct session_t { > session_t() : fd(make_unique_fd(0)) {} > session_t(const session_t&) = delete; > session_t& operator=(const session_t&) = delete; > session_t(session_t&& session) : fd(move(session.fd)) {} > session_t& operator=(session_t&& other) { > if (this != &other) { > fd = move(other.fd); > } > return *this; > } > > unique_fd fd; > > }; > > typedef unordered_map<int, session_t> session_map; > > Heres where the error pops up: > map.insert(make_pair(*session.fd, move(session))); > > Testing on GCC 4.4 Although your unique_fd is not defined, I believe your test case should work, using the insert member defined in [map.modifiers]. I suspect, but do not know, that this member is simply not implemented yet for GCC 4.4. -Howard -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Brian on 28 Apr 2010 16:52 On Apr 26, 11:50 am, Daniel Kr�gler <daniel.krueg...(a)googlemail.com> wrote: > On 26 Apr., 10:52, Brendan <catph...(a)catphive.net> wrote: > > > I'm trying to use a type that is moveable, but not copyable, in a > > standard container, in this case an unordered_map. When I try to > > insert it, I get complaints about a deleted copy constructor. I > > thought that move only objects were supported in standard containers? > > > Here's my type: > > > struct session_t { > > session_t() : fd(make_unique_fd(0)) {} > > session_t(const session_t&) = delete; > > session_t& operator=(const session_t&) = delete; > > session_t(session_t&& session) : fd(move(session.fd)) {} > > session_t& operator=(session_t&& other) { > > if (this != &other) { > > fd = move(other.fd); > > } > > return *this; > > } > > > unique_fd fd; > > }; > > > typedef unordered_map<int, session_t> session_map; > > > Heres where the error pops up: > > map.insert(make_pair(*session.fd, move(session))); > > This should work. It should also work more directly > by writing > > map.emplace(*session.fd, std::move(session)); > > instead. > I've been thinking about this topic recently and am wondering about the "more directly" there. Does the emplace version have, at least theoretically, an efficiency advantage over the insert version? TIA. Brian Wood http://webEbenezer.net (651) 251-9384 -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Mathias Gaunard on 29 Apr 2010 19:58
On 29 avr, 08:52, Brian <c...(a)mailvault.com> wrote: > I've been thinking about this topic recently and am wondering > about the "more directly" there. Does the emplace version > have, at least theoretically, an efficiency advantage over the > insert version? TIA. With emplace, you construct the pair directly into the container, while otherwise you construct a temporary that you move-construct later into the container. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |