C++中的继承和模板
Inheritance and templates in C++
我在继承和模板方面有以下问题:
class Base {};
class Deriv : public Base {};
template <class T> class X{};
void f(X<Base>& inst) {}
int main()
{
X<Base> xb;
f(xb);
X<Deriv> xd;
f(xd);
return 0;
}
程序无法编译,因为X<Base>
和X<Deriv>
之间没有关系。尽管如此,我认为应该可以做所有可以用X<Base>
也可以用X<Deriv>
做的事。除了将f
的函数体复制到新的函数void g(X<Deriv>& inst)
之外,我还能做些什么吗?
您可以继续使用模板:
template<class T>
void f(X<T>& inst) {}
将适用于X<Base>
和X<Derived>
.
编译器可能会复制代码(如果它不够智能),但您不必这样做。
为什么你认为它们应该相关?请考虑以下事项:
template<typename T>
class X;
template<>
class X<Base> {
int x;
};
template<>
class X<Deriv> {
double d;
};
它们绝对不能互换。所以不,这些类之间没有关系,你不能将一个传递给期望另一个的函数。您必须执行一些操作,例如使这两种类型都继承自公开所需接口的另一个通用类型。
<小时 />关于你的评论,你可以使用类型特征和static_assert
来做你在 Java 中会做的事情:
template<typename T>
void f(X<T>& inst) {
static_assert(std::is_base_of(Base, T)::value, "Template type must subclass Base");
// body of function...
}
如果您需要这样的功能,那么您必须在类型或重载上进行模板化,正如您所说。或者,您可以显式专用化X
以便X<Derived> : X<Base>
.
模板的不同实例化是不相关的类型,即使实例化模板参数是相关的。也就是说,无论A
和B
之间的关系如何,X<A>
都与X<B>
无关。
现在至于可以做什么,这取决于您的模板实际上是什么。 在某些情况下,您可以提供转换,以便可以将X<Derived>
转换为特定操作的X<Base>
。另一种选择是修改您的函数,以便能够接受T
派生自Base
的任何X<T>
(这可以通过创建模板并使用 SFINAE 禁止使用非派生自Base
的T
调用它来完成。同样,根据模板是什么,您可能能够提供对基础类型的访问,在这种情况下,函数可以引用Base
(考虑使用 .get()
方法shared_ptr
或unique_ptr
)
如果没有描述你真正想要完成的事情,就不可能提供一个好的选择。
这取决于。考虑X
std::shared_ptr
的情况。如果std::shared_ptr<Derived>
是从std::shared_ptr<Base>
派生的,则会破坏类型安全,而是存在隐式值转换。
但是,由于您是通过引用非const
传递的,因此这样的值转换不会直接帮助您。
其他可能性包括从公共接口继承和模板化函数。
- 继承函数的重载解析
- 继承期间显示未知行为的子类
- 头文件-继承c++
- 为什么在保护模式下继承升级不起作用
- 通过继承类使用来自不同命名空间的运算符
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 混合组合和继承的C++问题
- 继承:构造函数,初始化C++11中基类的类C数组成员
- 从类继承时,继承的类是否会通过父类重新定义继承的变量
- 公共与私人继承
- 如何创建从同一类继承的不同对象的向量
- 如何从另一个文件继承私有成员变量和公共函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 带有继承的C++工厂
- 我应该避免多重实现继承吗
- C++继承更改成员
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 关于C++中具有多重继承"this"指针的说明
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- 如何在QT Creator上将QWidget声明为继承类的对象