1

有人可以告诉我如何在 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

问候

4

3 回答 3

6

You can use std::is_base_of in combination with static_assert:

template<class T>
class MyClass
{
    static_assert( std::is_base_of< OtherClass, T >::value, "T does not extend OtherClass");

public:
    MyClass();
};

(you can, of course, also make OtherClass an additional template parameter in case you need to be more flexible)

于 2013-09-24T15:08:21.353 回答
1

如果您声明了一个模板类(即您使用template<class T, class OtherClass>的),那么您必须使用您声明的模板。由于您没有使用TOtherClassMyClass您收到编译器错误。

至于如何T extends OtherClass在C++中实现,不是那么简单,因为C++有多重继承,但是你可以使用里面的is_base_of函数stl

于 2013-09-24T15:08:26.140 回答
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,很可能它没有该名称的方法或字段,即使有,它也可能没有正确的类型,因此它可能无法编译。它基本上是鸭式的。

(不太可能,但可能的是,您有一个不同的、不相关的类型,它不是 的子类型,它还具有与 in中使用的OtherClass方法和类型相同的名称和类型的方法和字段,并且如果您尝试参数化对于那种类型,编译器不会抱怨它。然而,这种类型的存在可能是糟糕的设计,而且你不太可能在错误的地方意外使用这种类型。)OtherClassMyClassMyClass

于 2013-09-26T08:38:28.017 回答