Boost C++ Libraries: Ticket #6167: Assignment from a temporary of a class containing boost::unordered_map members fails with GNU GCC. https://svn.boost.org/trac10/ticket/6167 <p> With boost 1.48.0 the following code does not compile anymore: </p> <hr /> <p> #include &lt;boost/unordered_map.hpp&gt; </p> <p> struct A { </p> <blockquote> <p> boost::unordered_map&lt;int, int&gt; m; </p> </blockquote> <p> }; </p> <p> void Test() { </p> <blockquote> <p> A a;<br /> a = A(); </p> </blockquote> <p> } </p> <hr /> <p> GCC 4.6.1 &amp; GCC 4.1.2 say: </p> <blockquote> <p> 11:8: error: no match for ‘operator=’ in ‘a = A()’<br /> 11:8: note: candidate is:<br /> 4:8: note: A&amp; A::operator=(A&amp;)<br /> 4:8: note: no known conversion for argument 1 from ‘A’ to ‘A&amp;’<br /> </p> </blockquote> <p> When GCC 4.6.1 is set as C++11 compiler (-std=c++0x), it compiles without errors. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6167 Trac 1.4.3 anonymous Wed, 23 Nov 2011 11:25:00 GMT owner changed https://svn.boost.org/trac10/ticket/6167#comment:1 https://svn.boost.org/trac10/ticket/6167#comment:1 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Daniel James</span> to <span class="trac-author">Ion Gaztañaga</span> </li> </ul> <p> That's a limitation of Boost.Move's move emulation: </p> <p> <a href="http://www.boost.org/doc/html/move/emulation_limitations.html#move.emulation_limitations.assignment_operator">http://www.boost.org/doc/html/move/emulation_limitations.html#move.emulation_limitations.assignment_operator</a> </p> <p> I don't know if there's a good way round it. I'm reassigning to Ion to see if he's got any suggestions? </p> Ticket Geurt Vos <geurt.vos@…> Wed, 23 Nov 2011 13:20:16 GMT <link>https://svn.boost.org/trac10/ticket/6167#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6167#comment:2</guid> <description> <p> I see Boost.Move tells me how to work around it. Note also that assignment from map_list_of can't be done anymore (although that doesn't work at all when -std=c++0x, but that's not an unordered bug). So this will now also fail: </p> <blockquote> <p> boost::unordered_map&lt;int, int&gt; m;<br /> m = boost::assign::map_list_of(1, 1)(2, 2); </p> </blockquote> <p> I guess the only good way around it all ... is to provide two versions of all unordered containers (with &amp; without move). So one in 'boost' and one in 'boost::container'. </p> <p> If that isn't going to happen and if this is not considered a bug, but a limitation (or nuisance), I'd say these breaking changes should be well documented @ Boost.Unordered. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Wed, 23 Nov 2011 20:02:24 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6167#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6167#comment:3</guid> <description> <p> I don't see why assignments from map_list_of can't be done. map_list_of returns a container by value and that value can be assigned. Or am I missing something? </p> </description> <category>Ticket</category> </item> <item> <author>Geurt Vos <geurt.vos@…></author> <pubDate>Thu, 24 Nov 2011 09:04:59 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6167#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6167#comment:4</guid> <description> <p> this works: </p> <blockquote> <p> boost::unordered_map&lt;int, int&gt; m = boost::assign::map_list_of(1, 1)(2, 2); </p> </blockquote> <p> this doesn't: </p> <blockquote> <p> boost::unordered_map&lt;int, int&gt; m; <br /> m = boost::assign::map_list_of(1, 1)(2, 2); </p> </blockquote> <p> with the follow errors: </p> <blockquote> <p> move.hpp:233:7: error: ‘boost::rv&lt;T&gt;::~rv() [with T = boost::unordered::unordered_map&lt;int, int&gt;]’ is private <br /> test.cpp:14:28: error: within this context </p> </blockquote> <blockquote> <p> In file included from test.cpp:6:0: <br /> move.hpp: In member function ‘boost::assign_detail::generic_list&lt;T&gt;::operator Container() const [with Container = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;, T = std::pair&lt;int, int&gt;]’: <br /> test.cpp:14:28: instantiated from here </p> </blockquote> <blockquote> <p> move.hpp:233:7: error: ‘boost::rv&lt;T&gt;::~rv() [with T = boost::unordered::unordered_map&lt;int, int&gt;]’ is private <br /> list_of.hpp:436:81: error: within this context </p> </blockquote> <blockquote> <p> move.hpp:234:7: error: ‘boost::rv&lt;T&gt;::rv(const boost::rv&lt;T&gt;&amp;) [with T = boost::unordered::unordered_map&lt;int, int&gt;, boost::rv&lt;T&gt; = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;]’ is private <br /> list_of.hpp:436:81: error: within this context </p> </blockquote> <blockquote> <p> In file included from test.cpp:6:0: <br /> move.hpp: In member function ‘Container boost::assign_detail::converter&lt;DerivedTAssign, Iterator&gt;::convert_to_container() const [with Container = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;, DerivedTAssign = boost::assign_detail::generic_list&lt;std::pair&lt;int, int&gt; &gt;, Iterator = std::_Deque_iterator&lt;std::pair&lt;int, int&gt;, std::pair&lt;int, int&gt;&amp;, std::pair&lt;int, int&gt;*&gt;]’: <br /> list_of.hpp:436:81: instantiated from ‘boost::assign_detail::generic_list&lt;T&gt;::operator Container() const [with Container = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;, T = std::pair&lt;int, int&gt;]’ <br /> test.cpp:14:28: instantiated from here </p> </blockquote> <blockquote> <p> move.hpp:233:7: error: ‘boost::rv&lt;T&gt;::~rv() [with T = boost::unordered::unordered_map&lt;int, int&gt;]’ is private <br /> list_of.hpp:142:54: error: within this context </p> </blockquote> <blockquote> <p> move.hpp:234:7: error: ‘boost::rv&lt;T&gt;::rv(const boost::rv&lt;T&gt;&amp;) [with T = boost::unordered::unordered_map&lt;int, int&gt;, boost::rv&lt;T&gt; = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;]’ is private <br /> list_of.hpp:142:54: error: within this context </p> </blockquote> <blockquote> <p> list_of.hpp: In member function ‘Container boost::assign_detail::converter&lt;DerivedTAssign, Iterator&gt;::convert(const Container*, boost::assign_detail::default_type_tag) const [with Container = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;, DerivedTAssign = boost::assign_detail::generic_list&lt;std::pair&lt;int, int&gt; &gt;, Iterator = std::_Deque_iterator&lt;std::pair&lt;int, int&gt;, std::pair&lt;int, int&gt;&amp;, std::pair&lt;int, int&gt;*&gt;]’: <br /> list_of.hpp:142:54: instantiated from ‘Container boost::assign_detail::converter&lt;DerivedTAssign, Iterator&gt;::convert_to_container() const [with Container = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;, DerivedTAssign = boost::assign_detail::generic_list&lt;std::pair&lt;int, int&gt; &gt;, Iterator = std::_Deque_iterator&lt;std::pair&lt;int, int&gt;, std::pair&lt;int, int&gt;&amp;, std::pair&lt;int, int&gt;*&gt;]’ <br /> list_of.hpp:436:81: instantiated from ‘boost::assign_detail::generic_list&lt;T&gt;::operator Container() const [with Container = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;, T = std::pair&lt;int, int&gt;]’ <br /> test.cpp:14:28: instantiated from here </p> </blockquote> <blockquote> <p> list_of.hpp:163:46: error: no matching function for call to ‘boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;::rv(boost::assign_detail::converter&lt;boost::assign_detail::generic_list&lt;std::pair&lt;int, int&gt; &gt;, std::_Deque_iterator&lt;std::pair&lt;int, int&gt;, std::pair&lt;int, int&gt;&amp;, std::pair&lt;int, int&gt;*&gt; &gt;::iterator, boost::assign_detail::converter&lt;boost::assign_detail::generic_list&lt;std::pair&lt;int, int&gt; &gt;, std::_Deque_iterator&lt;std::pair&lt;int, int&gt;, std::pair&lt;int, int&gt;&amp;, std::pair&lt;int, int&gt;*&gt; &gt;::iterator)’ <br /> list_of.hpp:163:46: note: candidates are: <br /> move.hpp:234:7: note: boost::rv&lt;T&gt;::rv(const boost::rv&lt;T&gt;&amp;) [with T = boost::unordered::unordered_map&lt;int, int&gt;, boost::rv&lt;T&gt; = boost::rv&lt;boost::unordered::unordered_map&lt;int, int&gt; &gt;] <br /> move.hpp:234:7: note: candidate expects 1 argument, 2 provided <br /> move.hpp:232:7: note: boost::rv&lt;T&gt;::rv() [with T = boost::unordered::unordered_map&lt;int, int&gt;] <br /> move.hpp:232:7: note: candidate expects 0 arguments, 2 provided </p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>Daniel James</dc:creator> <pubDate>Thu, 24 Nov 2011 09:32:03 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6167#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6167#comment:5</guid> <description> <p> Boost.Unordered is not the place for documenting this, since I don't have a good understanding of the problem and don't wish to waste any time trying to. A link to the explanation in the move documentation is the best I can do. Which is actually a better solution from a maintenance point of view, as information written in unordered is likely to get dated if the situation change. Even if someone else volunteered to write it (unlikely as that is), they probably wouldn't be able to keep it up to date. </p> <p> I suppose Move could offer a quickbook file with some generic info to be included (using templates to insert appropriate names). I'm not sure how well that would work in practice though. Dropping a bunch of standard text into the middle of a document can have odd results. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Fri, 23 Dec 2011 12:38:49 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6167#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6167#comment:6</guid> <description> <p> I', afraid Boost.Assign will need some tweak to support Boost.Move </p> </description> <category>Ticket</category> </item> <item> <author>yurik@…</author> <pubDate>Tue, 05 Jun 2012 03:00:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/6167#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6167#comment:7</guid> <description> <p> In what seems to be either the same or related issue, on some versions of gcc (llvm-gcc-4.2 from Xcode on OS X, but not g++-4.1.2 in Linux) the following also does not compile (using the same 'struct A' from above): </p> <p> A a1, a2; std::swap(a1, a2); <em> Compile error inside generic non-specialized std::swap() when assigning "const Tmp tmp = ...;". </em></p> <p> On the other hand the originally described problem (simply 'A a; a = A();') occurs on both compilers I mentioned. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Mon, 15 Dec 2014 16:21:02 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/6167#comment:8 https://svn.boost.org/trac10/ticket/6167#comment:8 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> After three years, I'm afraid the best thing to do is to close the issue with wontfix. </p> Ticket