与 C++ 模板相比,Java 泛型更接近于将 a 填充boost::any
到变量中。self
试试看。默认情况下,C++ 模板创建的类型彼此之间没有运行时或动态关系。
您可以手动引入这种关系,例如通过共同的父级和类型擦除以及明智地使用pImpl
和智能指针。
C 类型的可变参数在 C++11 中已经过时了。可变模板参数是非常类型安全的,只要您的编译器支持它们(MSVC 2012 的 2012 年 11 月 CTP 支持它们(不是更新 1,CTP),clang 和非古代版本的 gcc 也是如此)。
C++ 中的模板是一种元编程,更接近于编写程序来编写程序,而不是 Java 泛型。Java Generic 有一个共享的“二进制”实现,而 C++ 模板的每个实例都是一个完全不同的“程序”(通过 COMDAT 折叠之类的过程,可以将其简化为一个二进制实现),其详细信息由模板描述代码。
template<typename T>
struct Field {
T data;
};
是一个小程序,上面写着“这里是如何创建字段类型”。当你传入一个int
anddouble
时,编译器会做大致这样的事情:
struct Field__int__ {
int data;
};
struct Field__double__ {
double data;
};
而且您不会期望这两种类型之间可以转换。
另一方面,Java 泛型创建如下内容:
struct Field {
boost::any __data__;
template<typename T>
T __get_data() {
__data__.get<T>();
}
template<typename T>
void __set_data(T& t) {
__data__.set(t);
}
property data; // reading uses __get_data(), writing uses __set_data()
};
whereboost::any
是一个容器,它可以容纳任何类型的实例,并且data
通过这些访问器对字段的访问重定向。
C++ 提供了使用模板元编程编写与 Java 泛型等效的方法的方法。要在 Java 中编写诸如 C++ 模板之类的东西,您必须让 Java 程序输出自定义 Java 字节或源代码,然后以允许调试器连接回将代码编写为源代码的方式运行该代码的错误。