Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#9799 closed Patches (wontfix)

polymorphic_downcast does not support virtual inheritance

Reported by: Camille Gillot <k1000.jlo@…> Owned by: No-Maintainer
Milestone: To Be Determined Component: utility
Version: Boost 1.54.0 Severity: Problem
Keywords: Cc:

Description

The following code barks at compilation :

#include <boost/cast.hpp>

class A {
public:
  virtual ~A();
};

class B
: public A
{};

class C
: public virtual A
{};

int main() {
  A* b = new B; A* c = new C;
  B* bb = boost::polymorphic_downcast<B*>(b); // Fine
  C* cc = boost::polymorphic_downcast<C*>(c); // Error

  delete b; delete c;
  return 0;
}

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.

Here is a patch doing it.

Attachments (2)

cast.diff (1.8 KB ) - added by Camille Gillot <k1000.jlo@…> 9 years ago.
cast.2.diff (1.9 KB ) - added by Camille Gillot <k1000.jlo@…> 9 years ago.
Corrected patch

Download all attachments as: .zip

Change History (4)

by Camille Gillot <k1000.jlo@…>, 9 years ago

Attachment: cast.diff added

comment:1 by Steven Watanabe, 9 years ago

Resolution: wontfix
Status: newclosed

The real question is whether should this be supported.

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.

It's also clear that the behavior is consistent with the documentation:

template <class Derived, class Base>
inline Derived polymorphic_downcast(Base* x);
// Effects: assert( dynamic_cast<Derived>(x) == x );
// Returns: static_cast<Derived>(x)

Also, your patch doesn't compile.

comment:2 by Camille Gillot <k1000.jlo@…>, 9 years ago

IMHO, in the case of virtual inheritance, dynamic_cast being the only viable way makes it the most efficient.

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.

Sorry for the patch, copy-paste errors come from a workaround used elsewhere. Here comes a corrected version of the patch (which does compile).

by Camille Gillot <k1000.jlo@…>, 9 years ago

Attachment: cast.2.diff added

Corrected patch

Note: See TracTickets for help on using tickets.