|
|
 |
 |
 |
 |
is_virtual_base<B, D> - possible?
While developing my own serialization library, I've found a need to detect, for a given pair of classes B and D, such that D directly derives from B, whether B is a virtual or non-virtual base of D. I've tried a few approaches to developing a template that would be able to resolve this, trying to use the inability to static_cast virtual bases to derived classes, and conversion ambiguity in overrides with covariant return types, but it seems that both approaches are dead- ends - they aren't usable for SFINAE. And I can't figure out what other quirks of the language can be used to detect virtual bases. In fact, is it even possible to do? Perhaps someone could share his experience in dealing with a similar problem?
On 29 May, 07:45, int@gmail.com wrote: > While developing my own serialization library, I've found a need to > detect, for a given pair of classes B and D, such that D directly > derives from B, whether B is a virtual or non-virtual base of D. I've > tried a few approaches to developing a template that would be able to > resolve this, trying to use the inability to static_cast virtual bases > to derived classes, and conversion ambiguity in overrides with > covariant return types, but it seems that both approaches are dead- > ends - they aren't usable for SFINAE. And I can't figure out what > other quirks of the language can be used to detect virtual bases. In > fact, is it even possible to do? Perhaps someone could share his > experience in dealing with a similar problem?
#include <boost/type_traits.hpp> template<class Base, class Derived> struct is_virtual_base_impl { struct In : Derived, virtual Base { }; enum { value = sizeof(In) == sizeof(Derived) }; };
template<class Base, class Derived> struct is_virtual_base { enum { value = boost::is_base_and_derived<Base, Derived>::value && is_virtual_base_impl<Base, Derived>::value }; };
I'm not sure this will work in all cases. you should check boost::serialization library, they must have something like this. DS
> struct is_virtual_base_impl > { > struct In : Derived, virtual Base > { > }; > enum { value = sizeof(In) == sizeof(Derived) }; > };
The sizeof() solution is the one I use currently, but it is horribly hackish - there are no guarantees about how the size of objects changes (or doesn't) with different flavors of inheritance. It seems to work with two compilers here, but not only it may not work on some other one, it can be easily broken by moving to a next version of those same compilers, so I'm rather uncomfortable with it. The only thing I can find in Boost is a vague mention of is_virtual_base in the TODO list for the next version of the serialization library. No code though, neither in the latest release, nor in the CVS (including sandbox).
On 1 Jun, 14:41, int@gmail.com wrote:
> > struct is_virtual_base_impl > > { > > struct In : Derived, virtual Base > > { > > }; > > enum { value = sizeof(In) == sizeof(Derived) }; > > }; > The sizeof() solution is the one I use currently, but it is horribly > hackish - there are no guarantees about how the size of objects > changes (or doesn't) with different flavors of inheritance. It seems > to work with two compilers here, but not only it may not work on some > other one, it can be easily broken by moving to a next version of > those same compilers, so I'm rather uncomfortable with it.
I'm not quite sure about this solution myself. Unfortunately every deficiency I can think of is implementation specific and not C++ standard issue. I was hoping that boost might have some compiler specific implementations. on the other hand, it will never answer true if the Base is not virtually inherited by Derived, so used in serialization library, it will always produce correct, albeit maybe not most efficient, code. > The only thing I can find in Boost is a vague mention of > is_virtual_base in the TODO list for the next version of the > serialization library. No code though, neither in the latest release, > nor in the CVS (including sandbox).
hmm. that is not very encouraging to hear. Why not ask at comp.lib.boost.devel . Maybe someone with more experience with different compilers has a more general solution. DS
|
 |
 |
 |
 |
|