我有一个相当独特的情况。
我有一个类似于以下代码的结构,其中类模板继承自己的模板参数,该参数可以是某个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
本身是唯一的。
此外,我无法使用多重继承(DerivedClass
和ClassTemplate
都有BaseClass
子类),因为这将导致菱形继承,从而创建继承层次结构对于简单的虚拟继承来说太复杂了。
答案 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 *>
。这避免了钻石继承问题。