Boost C++ Libraries: Ticket #9948: remove use of const_cast in intrusive containers https://svn.boost.org/trac10/ticket/9948 <p> In intrusive containers, the existing value traits customization mechanism described <a href="http://www.boost.org/doc/libs/1_55_0/doc/html/intrusive/value_traits.html">here</a> allows for value <code>pointer</code> to be a custom class. Moreover, the existing pointer traits mechanism allows for the user to: </p> <ul><li>Define and use a custom <code>pointer_traits&lt;pointer&gt;::reference</code> class instead of raw references. </li><li>Provide custom conversions between <code>pointer</code> and <code>reference</code>, and between <code>pointer</code> and <code>const_pointer</code>. </li></ul><p> That being said, in <code>list.hpp</code>, <code>slist.hpp</code>, <code>bstree.hpp</code> the C++ operator <code>const_cast</code> operator is used to convert a <code>const_reference</code> (defined as <code>pointer_traits&lt;const_pointer&gt;::reference</code>) into a <code>reference</code> (defined as <code>pointer_traits&lt;pointer&gt;::reference</code>). This happens in <code>[s_]iterator_to()</code> methods. This is unfortunate because <code>const_cast</code> cannot be overridden, and it cannot work with anything other than real pointers and real references. So even though most of the existing code base (through value traits &amp; pointer traits mechanisms) can support custom references, that possibility is removed by the use of <code>const_cast</code>. </p> <p> I created a pull request in that sense, where I replaced calls of the form: </p> <p> <code>const_cast&lt;reference&gt;(value)</code> (where <code>value</code> is a <code>pointer_traits&lt;const_pointer&gt;::reference</code>) </p> <p> by: </p> <p> <code>*pointer_traits&lt;pointer&gt;::const_cast_from(pointer_traits&lt;const_pointer&gt;::pointer_to(value))</code> </p> <p> This relies on the existence of: </p> <ol><li><code>const_pointer pointer_traits&lt;const_pointer&gt;::pointer_to(const_reference)</code>; </li><li><code>pointer pointer_traits&lt;pointer&gt;::const_cast_from(const_pointer)</code>; </li><li><code>reference pointer::operator * ()</code>. </li></ol><p> I think it is reasonable to expect all of these to be met. A user of raw references and raw pointers will be unaffected, because the default definitions of <code>pointer_traits</code> work as expected. As explained earlier, there is no existing code that uses custom references. That leaves only code with custom pointers and raw references to worry about breaking. </p> <p> Regarding 1, the <code>pointer_to()</code> method is used heavily by the boost intrusive code, so it is reasonable to expect any existing specialization of <code>pointer_traits</code> to provide that. </p> <p> Regarding 2, the <code>const_cast_from()</code> method, even though clearly documented in the pointer traits description, is not otherwise used in boost intrusive. So it is possible for existing code to specialize <code>pointer_traits</code> and not provide <code>const_cast_from</code>, which would result in broken code with the current modifications. I think the error message would be quite informative though: "missing const_cast_from", and easy to diagnose and fix. It would also be a step in the right direction: if a user really needs custom pointer traits, then they should really be providing the custom casts. </p> <p> As for 3, the <code>operator * ()</code> method, I think it's reasonable to expect a custom pointer class would provide that. Standard smart pointer classes provide that. In the future, I would also suggest adding this conversion explicitly in <code>pointer_traits</code>, e.g., require specializations to define <code>pointer_traits&lt;pointer&gt;::reference pointer_traits&lt;pointer&gt;::reference_from(pointer)</code>. </p> <p> The pull request is <a class="ext-link" href="https://github.com/boostorg/intrusive/pull/4"><span class="icon">​</span>here</a>. As explained, this removes <code>const_cast</code> from <code>list.hpp</code>, <code>slist.hpp</code>, and <code>bstree.hpp</code>. It is still used in <code>hashtable.hpp</code>, whose code looks a bit different than the other containers, so I left it alone. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9948 Trac 1.4.3 Ion Gaztañaga Thu, 01 May 2014 14:27:43 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9948#comment:1 https://svn.boost.org/trac10/ticket/9948#comment:1 <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> Thanks. I've reviewed the patch and spotted several more const_cast removals (in unordered containers). Detected [s_]iterator_to was not tested in many containers and fixed it. </p> <p> Fixed in develop branch: SHA-1: 7fc779ff0d28f0fcc603805eec00ac33442a045b </p> <ul><li>Fixed <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/9948" title="#9948: Feature Requests: remove use of const_cast in intrusive containers (closed: fixed)">#9948</a>: remove use of const_cast in intrusive containers. </li></ul><p> Added tests for [s_]iterator_to. </p> Ticket