0

The following is the simplified code to show my idea.

#include <iostream> 

struct base {
    virtual int test(){return 0;}
};

struct derived : public base {
    virtual int test(){return 1;}
};

template <typename T>
struct foo : public T {
    virtual int  bar() { return 2;}
};


typedef foo<base> foo_base;
typedef foo<derived> foo_derived;

int main(int argc, char ** argv) {

base * p = new derived(); //It is OK.
std::cout<<p->test()<<std::endl;

foo_base * foo_p = new foo_derived(); //It is not OK 
std::cout<<foo_p->bar()<<std::endl;

foo_base * foo_p2 =(foo_base *)(new foo_derived()); //It is working 
std::cout<<foo_p2->bar()<<std::endl;

delete foo_p2;
delete foo_p;
delete p;

return 0;
}

I know it is not OK due to the template changing the class inheritance. Is there an elegant way to make the inheritance keep the same after applying the template ?

More specifically, is it possible to build an inheritance between foo<base> and foo<derived>, for example, by using some proxy templates or special pattern like CRTP to rebuild same inheritance after the template instantiation?

whitebob
  • 48
  • 6

1 Answers1

0

As said by Sam Varshavchik in the comments, you cannot automate this process completely since C++ does not have reflection, and thus can't list base classes. However, you've already gone down the route of typedefing your template instantiations, and this is the perfect place to list base classes yourself (hanges highlighted in comments):

struct base {
    // Don't forget the virtual destructor for polymorphic destruction
    virtual ~base() = default;

    virtual int test() const { return 0; }
};

struct derived : base {
    int test() const override { return 1; }
};

// U... is the list of thebase classes for T
template <typename T, typename... U>
struct foo : T, foo<U>... {
    //        ^^^^^^^^^^^ Inheritance is mirrored here

    virtual int bar() const { return 2; }
};

// base has no base class
typedef foo<base> foo_base;

// derived has one base class, base.
typedef foo<derived, base> foo_derived;

Live example on Coliru

Quentin
  • 62,093
  • 7
  • 131
  • 191