I would like to determine at compile time if a pointer to Derived can be cast from a pointer to Base without dynamic_cast<>. Is this possible using templates and metaprogramm
Here is a solution for redirecting the compiler to do something depending on whether the class is a subclass of another or not.
class A
{};
class B : virtual public A
{};
class C : public A
{};
// Default template which will resolve for
// all classes
template
< typename T
, typename Enable = void
>
struct FooTraits
{
static void foo(){
std::cout << "normal" << std::endl;
}
};
// Specialized template which will resolve
// for all sub classes of A
template
< typename T
>
struct FooTraits
< T
, typename boost::enable_if
< boost::is_virtual_base_of< A, T>
>::type
>
{
static void foo(){
std::cout << "virtual base of A" << std::endl;
}
};
int main(int argc, const char * argv[] ){
FooTraits::foo(); // prints "normal"
FooTraits::foo(); // prints "virtual base of A"
}
and if you want to know how boost did it. If you have class Base and class Derived then the following holds.
struct X : Derived, virtual Base
{
X();
X(const X&);
X& operator=(const X&);
~X()throw();
};
struct Y : Derived
{
Y();
Y(const Y&);
Y& operator=(const Y&);
~Y()throw();
};
bool is_virtual_base_of = (sizeof(X)==sizeof(Y)));
It's a trick of using virtual inheritence with multiple inheritience. Multiple inheritience from the same virtual base does not result in duplicates of the virtual base class and therefore you can test this with sizeof.