将模板类作为一般参数,而不指定模板参数

时间:2014-05-16 12:55:32

标签: c++ templates inheritance

我有一个相当独特的情况。

我有一个类似于以下代码的结构,其中类模板继承自己的模板参数,该参数可以是某个BaseClass或其任何子类。

class BaseClass { 
... 
virtual void BaseMethod();
};

class DerivedClass { 
... 
virtual void BaseMethod(); // DerivedClass Overrides some of baseclass's methods

void DerivedMethod(); // And it has a few of its own
};

template <class T>
class ClassTemplate : public T {
...
// Some validation to ensure that this class template extends
// either BaseClass or one of its derived classes
void ValidateTemplate(const BaseClass& c) {}
...
}

这变得棘手的是当我想要获取一个模板类参数,该模板类参数是在基类或其子类之一后模板化的:

void func(ClassTemplate& c) { ... c.BaseMethod(); }

当然,这并没有编译为缺少模板参数。但是,我正在寻找一个功能如下的解决方案,而不必实际指定以下函数重载:

void func(ClassTemplate<BaseClass>& c) { ... c.BaseMethod(); }
void func(ClassTemplate<DerivedClass>& c) { ... c.BaseMethod(); }

最重要的是,我的其他类之一包含一个ClassTemplate指针列表:

class ClassWithList {
std::list<ClassTemplate<BaseClass>*> l;
...
}

通过上述内容,我希望列表l包含ClassTemplate<BaseClass>个对象和ClassTemplatE<DerivedClass>个对象。这有相同的根问题 - 希望后者可以解释为前者,就像C ++中大多数隐式转换的情况一样。这种特殊的转换是否可以与模板一起使用?或者是否有替代解决方法?

备注:

func中,没有使用DerivedClass个函数 - 就像我采用BaseClass参数一样,我希望能够访问其公共成员

然而,重要的是我不要以BaseClass为参数。这是因为我需要访问ClassTemplate对象的成员,这些成员对ClassTemplate本身是唯一的。

此外,我无法使用多重继承(DerivedClassClassTemplate都有BaseClass子类),因为这将导致菱形继承,从而创建继承层次结构对于简单的虚拟继承来说太复杂了。

1 个答案:

答案 0 :(得分:3)

根据您的描述,听起来您需要一个功能模板:

template <typename T>
void func(ClassTemplate<T>& c) { ... c.BaseMethod(); }

为了处理列表大小写,一个选项是使用第三个类作为接口:

struct ClassTemplateBase {
    virtual void doSomething() = 0;
};

template <class T>
class ClassTemplate : public T, public ClassTemplateBase {
  // ...
}

然后你可以拥有std::list<ClassTemplateBase *>。这避免了钻石继承问题。