Boost C++ Libraries: Ticket #11032: boost::offset_ptr needs explicit ctor https://svn.boost.org/trac10/ticket/11032 <p> Both the libc++ std library implementation and the MSVC library implementation require that their pointer types can be upcast. </p> <p> The list and tree data structures have a class hierarchy of node types and often seem to pass pointers to the base types (or to offset_ptr&lt;void&gt;) that are then upcast to the most derived types. offset_ptr has no explicit constructor that allows upcasts, only implicit ctors for downcasts. </p> <p> We have patched our version of offset_ptr with this constructor: </p> <pre class="wiki">//!Explicit constructor from other offset_ptr. Never throws. template&lt;class T2&gt; explicit offset_ptr(const offset_ptr&lt;T2, DifferenceType, OffsetType, OffsetAlignment&gt; &amp;ptr , typename ipcdetail::enable_if_c&lt; !ipcdetail::is_convertible&lt;T2*, PointedType*&gt;::value &gt;::type * = 0) : internal(ipcdetail::offset_ptr_to_offset&lt;OffsetType&gt;(static_cast&lt;PointedType*&gt;(ptr.get()), this)) {} </pre><p> </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11032 Trac 1.4.3 Ion Gaztañaga Wed, 11 Mar 2015 20:35:07 GMT <link>https://svn.boost.org/trac10/ticket/11032#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11032#comment:1</guid> <description> <p> I can't see the problem. offset_ptr has a constructor that allows conversions: </p> <pre class="wiki">//!Constructor from other offset_ptr. If pointers of pointee types are //!convertible, offset_ptrs will be convertibles. Never throws. template&lt;class T2&gt; offset_ptr( const offset_ptr&lt;T2, DifferenceType, OffsetType, OffsetAlignment&gt; &amp;ptr #ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED , typename ipcdetail::enable_if_c&lt; ipcdetail::is_convertible&lt;T2*, PointedType*&gt;::value &amp;&amp; ipcdetail::offset_ptr_maintains_address&lt;T2, PointedType&gt;::value &gt;::type * = 0 #endif ) : internal(static_cast&lt;OffsetType&gt; (ipcdetail::offset_ptr_to_offset_from_other&lt;0&gt;(this, &amp;ptr, ptr.get_offset()))) {} //!Constructor from other offset_ptr. If pointers of pointee types are //!convertible, offset_ptrs will be convertibles. Never throws. template&lt;class T2&gt; offset_ptr( const offset_ptr&lt;T2, DifferenceType, OffsetType, OffsetAlignment&gt; &amp;ptr , typename ipcdetail::enable_if_c&lt; ipcdetail::is_convertible&lt;T2*, PointedType*&gt;::value &amp;&amp; !ipcdetail::offset_ptr_maintains_address&lt;T2, PointedType&gt;::value &gt;::type * = 0) : internal(static_cast&lt;OffsetType&gt; (ipcdetail::offset_ptr_to_offset&lt;0&gt;(static_cast&lt;PointedType*&gt;(ptr.get()), this))) {} </pre><p> this allows upcasting (from derived to base). Did you mean that offset_ptr does not support downcasting (from base to derived)? It does that for good safety reasons as raw pointers don't allow those conversions. Do you want this to compile? </p> <p> offset_ptr&lt;Base&gt; pb = ...; offset_ptr&lt;Derived&gt;pd(p); </p> <p> whereas this is a compilation error </p> <p> Base *pb = ... Derived *pd = pb; </p> <p> ? </p> </description> <category>Ticket</category> </item> <item> <author>stheophil@…</author> <pubDate>Thu, 12 Mar 2015 09:21:24 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11032#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11032#comment:2</guid> <description> <p> Yes, I want it to support downcasting. Sorry. </p> <pre class="wiki">offset_ptr&lt;Base&gt; pb = ...; offset_ptr&lt;Derived&gt;pd(pb); </pre><p> Does not have to compile because, as you say, raw pointers do not support this conversion, but </p> <pre class="wiki">offset_ptr&lt;Base&gt; pb = ...; offset_ptr&lt;Derived&gt;pd = static_cast&lt;offset_ptr&lt;Derived&gt;&gt;(pb); </pre><p> should compile and by consequence </p> <pre class="wiki">offset_ptr&lt;Base&gt; pb = ...; offset_ptr&lt;Derived&gt;pd = (offset_ptr&lt;Derived&gt;)pb; </pre><p> too, which just does a static_cast if I understand correctly. Both are used a lot in std::list and std::map implementations of Clang and MSVC. </p> </description> <category>Ticket</category> </item> <item> <author>Chris Clearwater <chris@…></author> <pubDate>Tue, 17 Nov 2015 14:29:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11032#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11032#comment:3</guid> <description> <p> Please see the table here: <a class="ext-link" href="http://en.cppreference.com/w/cpp/concept/Allocator"><span class="icon">​</span>http://en.cppreference.com/w/cpp/concept/Allocator</a> </p> <p> The C++11 standard requires <code>static_cast&lt;A::pointer&gt;(vptr)</code> to succeed. </p> <p> I have also run into this problem when trying to use my own container, which uses void_pointer to store child pointers, with Boost.Interprocess. </p> </description> <category>Ticket</category> </item> </channel> </rss>