Eva*_*Eva 18 c# c++ java generics templates
我理解C++中与Java和C#中的泛型不同的模板方面.C#是一种物化,Java使用类型擦除,C++使用duck typing等.C++模板可以做许多事情,Java和C#泛型不能(例如模板特化).但是Java泛型可以做的事情有很多,C#和C++都做不到(例如,制作一个泛型系列的有界类型参数 C#泛型可以做的事情,而Java和C++不能做的事情(例如运行时泛型反射).[编辑:显然Java泛型比我想象的要弱得多.(这是在说些什么.)无论如何,尽管它们无能为力,但它们仍然被认为是仿制药和C#的仿制药.class Foo<T extends Comparable<?>>),以及
我不明白的是概念上使模板与泛型不同.C++模板的哪些部分是不能在不是模板的东西中完成的东西,而是通用的?例如,如果我要实现支持模板的语言,那么绝对需要什么呢?我可以忽略哪些语言支持泛型所必需的?
我的猜测是模板是一组超级泛型,或者它们是实现泛型的一种方式,但我真的不明白真正的模板和真正的模板之间的区别.
嗯..如果你说你深入理解C++模板并且说你没有看到/感觉到泛型和它们之间的区别,那么,很可能你是对的:)
有很多不同之处将描述仿制药如何/为什么比模板更好,列出大量的差异等等,但这与这个想法的核心无关.
我们的想法是允许更好的代码重用.模板/泛型为您提供了一种构建某种高阶类定义的方法,这些类定义抽象了一些实际类型.
在这个术语中,它们之间没有区别,唯一的区别是由底层语言和运行时的特定功能和约束强制执行的区别.
有人可能会争辩说,泛型提供了一些额外的功能(通常在谈论对象类树的动态内省时),但很少有(如果有的话)无法在C++的模板中手动实现.通过一些努力,大多数都可以实现或模拟,因此它们不能区分"适当的泛型"和"真实的模板".
其他人会争辩说,由于C++的复制粘贴行为,可用的优化潜力很大.对不起,不是真的.Java和C#中的JIT也可以做到,差不多,但做得很好.
然而,有一件事可以使Java/C#的泛型成为C++模板功能的真正子集.你甚至提到过它!
它是模板专业化.
在C++中,每个特化都表现为完全不同的定义.
在C++中,template<typename T> Foo专门用于T == int可能看起来像:
class Foo<int>
{
void hug_me();
int hugs_count() const;
}
Run Code Online (Sandbox Code Playgroud)
而专用于T == MyNumericType的"相同"模板可能看起来像
class Foo<MyNumericType>
{
void hug_me();
MyNumericType get_value() const;
void reset_value() const;
}
Run Code Online (Sandbox Code Playgroud)
仅供参考:那只是伪代码,不会编译:)
Java和C#的泛型都不能做到这一点,因为它们的定义表明所有泛型类型实现都将具有相同的"用户界面".
更重要的是,C++使用SFINAE规则.模板可能存在许多"理论上冲突"的特殊化定义.但是,在使用模板时,只使用那些"实际上好"的模板.
使用类似于上面示例的类,如果您使用:
Foo<double> foood;
foood.reset_value();
Run Code Online (Sandbox Code Playgroud)
只会使用第二个特化,因为第一个不能编译,因为..."reset_value"缺失.
使用泛型,你不能这样做.您需要创建一个包含所有可能方法的泛型类,然后在运行时动态检查内部对象并为不可用的方法抛出一些"未实现"或"不支持"的异常.那......太可怕了.这样的事情应该可以在编译时完成.
模板专业化和SFINAE的实际功能,含义,问题和整体复杂性是真正区分泛型和模板的.简单地说,泛型是以这样的方式定义的,专业化是不可能的,因此SFINAE是不可能的,因此,整个机制矛盾地更容易/更简单.
在编译器的内部实现更简单/更简单,并且非智能大脑可以理解.
虽然我同意Java/C#中泛型的整体优势,但我真的很想念专业化,界面灵活性和SFINAE规则.但是,如果我没有提及与理智的OO设计相关的一个重要事项,那我就不公平了:如果xxx类型的模板专业化实际上改变了它的客户端API,那么很可能它应该以不同的名称命名并且应该形成不同的模板.模板可以做的所有额外好处大多都添加到工具集中,因为...在C++中没有反射,必须以某种方式进行模拟.SFINAE是编译时反射的一种形式.
因此,差异世界中最大的玩家被减少到应用于掩盖运行时缺陷的修补程序的好奇(有益)副作用,这几乎完全缺乏运行时内省:))
因此,我说除了laguage强制执行的某些任意操作之外没有其他区别,或者运行时平台强制执行某些任意操作.
所有这些只是高阶类或函数/方法的一种形式,我认为这是最重要的事情和特征.