is_virtual_base<B, D> - possible?

I

int19h

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?
 
D

dasjotre

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
 
I

int19h

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).
 
D

dasjotre

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,228
Latest member
MikeMichal

Latest Threads

Top