Boost C++ Libraries: Ticket #12194: Copy assignment on moveable and copyable classes uses wrong type https://svn.boost.org/trac10/ticket/12194 <p> A patch introduced a breaking change to classes that are copyable and movable: <a class="ext-link" href="https://github.com/boostorg/move/commit/4f9c2b62fbdcf5995ecf50a2ecf2494048a6696d#diff-6a11d48d06dd33c1193ffb3d794787fbR252"><span class="icon">​</span>https://github.com/boostorg/move/commit/4f9c2b62fbdcf5995ecf50a2ecf2494048a6696d#diff-6a11d48d06dd33c1193ffb3d794787fbR252</a> </p> <p> The macro was changed so the <code>TYPE&amp; operator=(TYPE &amp;t)</code> calls the assignement operator with a type <code> const TYPE&amp; </code> instead of <code> const ::boost::rv&lt;TYPE&gt; &amp; </code> </p> <p> This change is not described and seems to be a mistake that was not caught in the review process. As the macro <code> BOOST_COPY_ASSIGN_REF </code> still expands to the original rv-type a wrong operator might get called. A minimum example: </p> <pre class="wiki">#include &lt;boost/move/move.hpp&gt; #include &lt;cassert&gt; class Foo{ BOOST_COPYABLE_AND_MOVABLE(Foo) public: int i; explicit Foo(int val): i(val){} Foo(BOOST_RV_REF(Foo) obj): i(obj.i) {} Foo&amp; operator=(BOOST_RV_REF(Foo) rhs){ i = rhs.i; return *this; } Foo&amp; operator=(BOOST_COPY_ASSIGN_REF(Foo) rhs){ i = rhs.i; return *this; } template&lt;class OTHER&gt; Foo&amp; operator=(const OTHER&amp; rhs){ i = rhs.j; return *this; } }; struct Bar{ int j; explicit Bar(int val): j(val){} }; int main(){ Foo foo1(1); Foo foo2(2); Bar bar(3); assert(foo1.i == 1); assert(foo2.i == 2); assert(bar.j == 3); foo2 = foo1; assert(foo1.i == 1); assert(foo2.i == 1); foo1 = bar; assert(foo1.i == 3); return 0; } </pre><p> This compiles and works fine in boost &lt;=1.58 but fails in &gt;=1.59 as the template version is called. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/12194 Trac 1.4.3 a.grund@… Thu, 12 May 2016 11:48:43 GMT <link>https://svn.boost.org/trac10/ticket/12194#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12194#comment:1</guid> <description> <p> I found during creation of a patch (<a class="ext-link" href="https://github.com/boostorg/move/pull/9"><span class="icon">​</span>https://github.com/boostorg/move/pull/9</a>) that <code> BOOST_COPY_ASSIGN_REF </code> causes more problems. The class assignment fails also, when assigning const instances as that would also use the template function In C++11 it works perfectly though </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Thu, 30 Jun 2016 10:25:16 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/12194#comment:2 https://svn.boost.org/trac10/ticket/12194#comment:2 <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">fixed</span> </li> </ul> <p> Patch was applied: </p> <p> <a class="ext-link" href="https://github.com/boostorg/move/commit/b474e8c28a96d87763cccb9a33b5ff4b169482d3"><span class="icon">​</span>https://github.com/boostorg/move/commit/b474e8c28a96d87763cccb9a33b5ff4b169482d3</a> </p> Ticket a.grund@… Thu, 30 Jun 2016 11:10:10 GMT <link>https://svn.boost.org/trac10/ticket/12194#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12194#comment:3</guid> <description> <p> Follow-up issue: <a class="ext-link" href="https://svn.boost.org/trac/boost/ticket/12307"><span class="icon">​</span>https://svn.boost.org/trac/boost/ticket/12307</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Tue, 05 Jul 2016 21:21:19 GMT</pubDate> <title>status changed; resolution deleted https://svn.boost.org/trac10/ticket/12194#comment:4 https://svn.boost.org/trac10/ticket/12194#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> The patch breaks several Boost libraries (Container and Intrusive) so it's reverted: </p> <p> <a class="ext-link" href="https://github.com/boostorg/move/commit/1194a39ab3195a17c849e1d11f4305ff6727df8b"><span class="icon">​</span>https://github.com/boostorg/move/commit/1194a39ab3195a17c849e1d11f4305ff6727df8b</a> </p> <p> The alternative is to document this limitation with templated assignments, similarly to Issue <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/12307" title="#12307: Bugs: Copy assignment from const ref handled differently in C++11/C++98 (closed: fixed)">#12307</a>. </p> Ticket a.grund@… Wed, 06 Jul 2016 08:17:36 GMT <link>https://svn.boost.org/trac10/ticket/12194#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12194#comment:5</guid> <description> <p> This is strange as it returns a 'const rv&lt;...&gt;&amp;' which should be ok and is also documented this way. </p> <p> If the other libraries can't be fixed, please document this back to 1.59 as that change was silently introduced (no release note) and changes the observed and documented behaviour: </p> <p> "const rvalue and lvalues, bind to const ::boost::rv&lt; TYPE &gt;&amp;" </p> <p> But now it seems it is like: "const rvalue and lvalues, bind to const ::boost::rv&lt; TYPE &gt;&amp; OR const TYPE&amp;" or a mix of both depending on some unknown conditions. </p> <p> This makes it very hard to use this in non-trivial/templated contexts </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Fri, 29 Jul 2016 09:56:33 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/12194#comment:6 https://svn.boost.org/trac10/ticket/12194#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Documented limitation and possible workaround in commit: </p> <p> <a class="ext-link" href="https://github.com/boostorg/move/commit/cfd6be4ab46223917cb79e7dd856f582df587d7d"><span class="icon">​</span>https://github.com/boostorg/move/commit/cfd6be4ab46223917cb79e7dd856f582df587d7d</a> </p> Ticket