如何使模板化的类保持继承?

时间:2018-05-05 19:23:48

标签: c++ templates inheritance

以下是显示我的想法的简化代码。

#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;
}

我知道由于模板更改了类继承而不行。应用模板后,有一种优雅的方法可以使继承保持不变吗?

更具体地说,是否可以在foo<base>foo<derived>之间构建继承,例如,通过使用某些代理模板或特殊模式(如CRTP)在模板实例化后重建相同的继承?

1 个答案:

答案 0 :(得分:0)

如评论中Sam Varshavchik所述,由于C ++没有反射,因此无法完全自动化此过程,因此无法列出基类。但是,您已经走过了typedef模板实例化的路线,这是自己列出基类的最佳位置(评论中突出显示的内容):

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