具有模板化基类的Diamond继承:Base <Derived>

时间:2019-10-13 21:01:49

标签: c++ templates inheritance diamond-problem

从以派生类作为模板参数的模板化基类继承时,我遇到钻石问题。

通常这个问题可以通过如下的虚拟继承解决:

class Base0
{
protected:
    int var = 0;
};

class Base1 : public virtual Base0
{
};

class Base2 : public virtual Base0
{

};

class Derived :
    public Base1,
    public Base2
{
public:
    void f()
    {
        var = 1; // OK single var
    }
};

但是我有这种情况:

template<typename DERIVED_CLASS>
class TemplatedBase0
{
protected:
    int var = 0;
};

class Base1 : public virtual TemplatedBase0<Base1>
{
};

class Base2 : public virtual TemplatedBase0<Base2>
{

};

class Derived :
    public Base1,
    public Base2
{
public:
    void f()
    {
        var = 1; // ERROR: var is ambigous
    }
};

我了解在以上情况下,模板化的基类是不同的,即有2个完全未实现的基类,看起来像是虚拟继承文档。

所以我的问题是,有什么办法可以使这项工作成功吗?我应该在这里采用什么设计/方法?

我需要有基类作为模板,它采用派生类类型。但是如何使钻石继承成为可能?

2 个答案:

答案 0 :(得分:1)

您的代码中没有菱形。您的Derived有两个不同的var。取决于您要写的内容:

Base1::var = 1;
Base2::var = 1;
  

但是如何使钻石继承成为可能?

不清楚为什么要钻石。如果您的目标是在var中只有一个Derived,则需要使用其他设计。

答案 1 :(得分:1)

如果只想在int var;中只有一个Derived,则需要将其移至非模板基类:

class GenericTemplatedBase0
{
  protected:
    int var = 0;
};

template<typename DERIVED_CLASS>
class TemplatedBase0 : virtual public GenericTemplatedBase0
{
    // ...
};

class Base1 : public TemplatedBase0<Base1>
{
};

class Base2 : public TemplatedBase0<Base2>
{
};

class Derived : public Base1, public Base2
{
  public:
    void f()
    {
        var = 1;
    }
};