栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

是什么使模板与通用模板不同?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

是什么使模板与通用模板不同?

嗯..如果您说您深入理解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;}

而专门用于T == MyNumericType的“相同”模板可能看起来像

class Foo<MyNumericType> {    void hug_me();    MyNumericType get_value() const;    void  reset_value() const;}

仅供参考:这只是伪代码,不会编译:)

Java和C#的泛型都无法做到这一点,因为它们的定义表明所有泛型类型实现将具有相同的“用户界面”。

更重要的是,C ++使用SFINAE规则。模板可能存在许多“理论上相撞”的专业定义。但是,在使用模板时,仅使用那些“实际良好”的模板。

如果使用与上面的示例类似的类,请使用:

 Foo<double> foood; foood.reset_value();

仅使用第二个专业化,因为由于缺少“ reset_value”,第一个专业化无法编译。

使用泛型,您将无法做到这一点。您需要创建一个具有所有可能方法的通用类,然后在运行时动态检查内部对象,并对不可用方法抛出一些“未实现”或“不支持”的异常。那太可怕了。这样的事情在编译时应该是可能的。

模板专业化SFINAE
的实际功能,影响,问题和整体复杂性是真正区分泛型和模板的真正原因。简而言之,泛型是以这样的方式定义的,即不可能进行专门化,因此不可能进行SFINAE,因此,矛盾的是,整个机制更容易/更简单。

在编译器内部更容易/更容易实现,并且非熟练者也可以理解。

尽管我同意Java /
C#中泛型的整体优点,但我确实错过了专业化,接口灵活性和SFINAE规则。但是,如果我不提及与明智的OO设计有关的一件重要事情,那我就不公平:如果您对xxx类型的模板专业化实际上改变了它的客户端API,那么很可能应该以不同的方式命名它,并形成一个不同的模板。模板可以完成的所有其他操作都被添加到工具集中,因为…在C
++中没有反射,因此必须以某种方式进行仿真。SFINAE是编译时反射的一种形式。

因此,差异世界中最大的参与者被减少为应用修补程序来掩盖运行时的不足,这几乎是完全缺乏运行时自省的一种奇怪的(有益的)副作用:))

因此,我说除了由laguage强制执行的某些任意操作或由运行时平台强制执行的某些任意操作之外,没有其他区别。

它们都是高阶类或函数/方法的一种形式,我认为这是最重要的事情和功能。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/470484.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号