有人可以告诉我如何在C ++中实现这个Java代码吗?
public class MyClass<T extends OtherClass>{
....
}
我用C ++测试了这个:
template<class T, class OtherClass>
class MyClass
{
public:
MyClass();
}
但我收到错误:invalid use of template-name 'MyClass' without an argument list
问候
答案 0 :(得分:6)
您可以将std::is_base_of
与static_assert
结合使用:
template<class T>
class MyClass
{
static_assert( std::is_base_of< OtherClass, T >::value, "T does not extend OtherClass");
public:
MyClass();
};
(当然,您也可以使OtherClass
成为额外的模板参数,以防您需要更灵活。
答案 1 :(得分:1)
如果您声明了一个模板化的类(即您使用template<class T, class OtherClass>
所做的事情),那么您必须使用您声明的模板。由于您未在T
中使用OtherClass
或MyClass
,因此会出现编译错误。
至于如何在C ++中实现T extends OtherClass
,它不是那么简单,因为C ++有多重继承,但你可以使用is_base_of
中的stl
函数
答案 2 :(得分:1)
通常,在C ++中你只需使用:
template<class T>
class MyClass
您无需说出extends OtherClass
之类的内容。
以下是解释:
在C ++和Java中,当您访问对象的方法或字段时,编译器必须确保对象表达式的静态类型支持该方法或字段,否则将无法编译。
在Java中,泛型类和方法只编译一次。编译泛型类或方法时,不知道类型参数(如T
)是什么或可能是什么类型。因此,必须使边界使编译器允许访问Object
未提供的方法和字段。绑定T extends OtherClass
的原因是因为MyClass
中的某个地方,它会尝试访问由T
提供的OtherClass
类型的表达式上的方法或字段。因此,此绑定允许编译器进行类型检查并成功编译。
相比之下,在C ++中,模板化的类和方法针对每个不同的类型参数(称为模板的每个“实例化”)编译一次,就像编译器复制并粘贴模板代码的副本并替换实际类型一样代码中每次出现T
的参数。因此,在编译模板化的类或方法时,确切地知道T
是什么类型。像Java一样,绑定的规范是不必要的,因为编译器可以直接检查T
的类型是否支持给定的方法或字段。如果T
是OtherClass
的子类型,则会成功编译。如果T
不是OtherClass
的子类型,则很可能它没有该名称的方法或字段,即使它有,也可能没有正确的类型,所以它可能无法编译。它基本上是鸭子打字。
(不太可能,但有可能,你有一个不同的,不相关的类型,不是OtherClass
的子类型,它也有与{{1}中的方法和类型相同的方法和字段在OtherClass
中使用的,如果你尝试用这种类型参数化MyClass
,编译器就不会抱怨它。但是,这种类型的设计可能不好,你不太可能不小心在错误的地方使用这种类型。)