将模板类作为通用参数,而不指定模板参数

Taking template class as a general argument, without specifying template arguments

本文关键字:参数      更新时间:2023-10-16

我遇到了一个相当独特的情况。

我有一个类似于下面代码的结构,其中一个类模板继承自它自己的模板参数,这可能是一个特定的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(); }

在此之上,我的另一个类包含一个classstemplate指针列表:

class ClassWithList {
std::list<ClassTemplate<BaseClass>*> l;
...
}
在上面的代码中,我希望列表l同时包含ClassTemplate<BaseClass>对象和ClassTemplatE<DerivedClass>对象。这有同样的根本问题——希望后者可以被解释为前者,就像c++中大多数隐式转换的情况一样。这种特殊的转换可以用模板实现吗?或者有其他的解决方法吗?

指出:

func中,没有使用DerivedClass的函数-就像如果我接受了BaseClass参数一样,我希望能够访问它的公共成员。

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

此外,我不能求助于使用多重继承(有DerivedClass子类ClassTemplateBaseClass),因为这将导致钻石继承,从而创建一个继承层次结构过于复杂的简单的虚拟继承。

从你的描述中,听起来你想要一个函数模板:

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 *>。这避免了菱形继承问题。