Boost C++ Libraries: Ticket #9799: polymorphic_downcast does not support virtual inheritance https://svn.boost.org/trac10/ticket/9799 <p> The following code barks at compilation : </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;boost/cast.hpp&gt;</span><span class="cp"></span> <span class="k">class</span> <span class="nc">A</span> <span class="p">{</span> <span class="k">public</span><span class="o">:</span> <span class="k">virtual</span> <span class="o">~</span><span class="n">A</span><span class="p">();</span> <span class="p">};</span> <span class="k">class</span> <span class="nc">B</span> <span class="o">:</span> <span class="k">public</span> <span class="n">A</span> <span class="p">{};</span> <span class="k">class</span> <span class="nc">C</span> <span class="o">:</span> <span class="k">public</span> <span class="k">virtual</span> <span class="n">A</span> <span class="p">{};</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">A</span><span class="o">*</span> <span class="n">b</span> <span class="o">=</span> <span class="k">new</span> <span class="n">B</span><span class="p">;</span> <span class="n">A</span><span class="o">*</span> <span class="n">c</span> <span class="o">=</span> <span class="k">new</span> <span class="n">C</span><span class="p">;</span> <span class="n">B</span><span class="o">*</span> <span class="n">bb</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">polymorphic_downcast</span><span class="o">&lt;</span><span class="n">B</span><span class="o">*&gt;</span><span class="p">(</span><span class="n">b</span><span class="p">);</span> <span class="c1">// Fine</span> <span class="n">C</span><span class="o">*</span> <span class="n">cc</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">polymorphic_downcast</span><span class="o">&lt;</span><span class="n">C</span><span class="o">*&gt;</span><span class="p">(</span><span class="n">c</span><span class="p">);</span> <span class="c1">// Error</span> <span class="k">delete</span> <span class="n">b</span><span class="p">;</span> <span class="k">delete</span> <span class="n">c</span><span class="p">;</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><p> static_cast cannot handle downcast from or through a virtual base class, dynamic_cast must be used instead. A fix would be to test the case of virtual base class with boost::is_virtual_base_of and dispatch the two cases. </p> <p> Here is a patch doing it. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9799 Trac 1.4.3 Camille Gillot <k1000.jlo@…> Thu, 20 Mar 2014 16:34:54 GMT attachment set https://svn.boost.org/trac10/ticket/9799 https://svn.boost.org/trac10/ticket/9799 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">cast.diff</span> </li> </ul> Ticket Steven Watanabe Thu, 20 Mar 2014 17:34:20 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9799#comment:1 https://svn.boost.org/trac10/ticket/9799#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">wontfix</span> </li> </ul> <p> The real question is whether should this be supported. </p> <p> From the documentation: "... or when efficiency is not important, polymorphic_cast is preferred." Since we have to do a dynamic_cast anyway, efficiency really doesn't matter. </p> <p> It's also clear that the behavior is consistent with the documentation: </p> <div class="wiki-code"><div class="code"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">class</span> <span class="nc">Derived</span><span class="p">,</span> <span class="k">class</span> <span class="nc">Base</span><span class="o">&gt;</span> <span class="kr">inline</span> <span class="n">Derived</span> <span class="n">polymorphic_downcast</span><span class="p">(</span><span class="n">Base</span><span class="o">*</span> <span class="n">x</span><span class="p">);</span> <span class="c1">// Effects: assert( dynamic_cast&lt;Derived&gt;(x) == x );</span> <span class="c1">// Returns: static_cast&lt;Derived&gt;(x)</span> </pre></div></div><p> Also, your patch doesn't compile. </p> Ticket Camille Gillot <k1000.jlo@…> Thu, 20 Mar 2014 23:29:11 GMT <link>https://svn.boost.org/trac10/ticket/9799#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9799#comment:2</guid> <description> <p> IMHO, in the case of virtual inheritance, dynamic_cast being the only viable way makes it the most efficient. </p> <p> Still, this function not handling virtual inheritance should be documented : the current documentation does not tell anything about this case. Moreover, I don't think that static_cast's not handling this case is well-known enough. </p> <p> Sorry for the patch, copy-paste errors come from a workaround used elsewhere. Here comes a corrected version of the patch (which does compile). </p> </description> <category>Ticket</category> </item> <item> <author>Camille Gillot <k1000.jlo@…></author> <pubDate>Thu, 20 Mar 2014 23:30:19 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/9799 https://svn.boost.org/trac10/ticket/9799 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">cast.2.diff</span> </li> </ul> <p> Corrected patch </p> Ticket