如何为模板类参数指定必需的继承?

时间:2014-01-08 18:15:14

标签: c++ templates

我有以下结构:

class ElementEx
{
public:
    ElementEx() {}
    AddChild(ElementEx* element) 
    {
        // some stuff
    }
};

class A : ElementEx
{
public:
    A() {}
};

class B : ElementEx
{
public:
    B() {}
};


template <class T>
class MyNewClass : public T
{
public:
    MyNewClass()
    {
        ElementEx* newElement = new ElementEx();
        AddChild(newElement);
    }
};

创建MyNewClass对象时,T必须从A或B继承,因此MyNewClass将从ElementEx继承。但在我的例子中,编译器不知道这一点,也无法弄清楚AddChild是什么。如何确保T类是ElementEx的后代?

我在想什么

((ElementEx*)this)->AddChild(newElement);

但这看起来真的很不优雅(并且容易出错,如果错误的类型以T形式输入),我认为必须有更好的方法来做到这一点。

3 个答案:

答案 0 :(得分:3)

编译器在这里抱怨,因为它不知道AddChild在第一次传递期间依赖于TAddChild可以通过在this->之前添加呼叫来使T成为依赖名称,从而在{{1}}已知时将查询延迟到第二次传递。

答案 1 :(得分:2)

只要您满足于父类支持AddChild接受ElementEx,您就可以使用正常的编译器错误轻松完成此操作。

在你的代码中修复了一堆错误后(A和B私有继承,你的所有类都有私有构造函数,AddChild没有返回类型)我能通过添加{{1}使其工作正常调用this->因为AddChild是一个从属名称,你可以通过限定类型或添加AddChild来向编译器指明。如果您不需要对该方法进行虚拟调用,则可以通过调用this->来强制执行正确的查找。修正后的代码如下。

ElementEx::AddChild

答案 2 :(得分:1)

有几种方法可以很好地完成这项工作,但它们都有使用1.)静态断言的基础。 2)静态评估函数。

Personaly,我会使用(在构造函数中)

static_assert(std::is_base_of<ElementEx,T>::value,"T must derive from ElementEx")

但可能有更好的方法。你的问题的X部分是什么(你想用这个奇怪的继承结构实现什么?)