注册 登录
编程论坛 C++教室

求指教,求鞭笞,求虐待,关于模板;

yaobao 发布于 2013-01-16 16:26, 836 次点击
在书上看到template<typename T>和tmpelate<class T>都是定义模板,这两样有区别吗? 区别在哪?谢谢!!
求虐待,求教育!
19 回复
#2
rjsp2013-01-16 16:36
仅在此处是没有区别的
#3
yaobao2013-01-16 16:40
那什么地方有区别啊,我小菜,求指教啊
#4
rjsp2013-01-16 16:43
回复 3楼 yaobao
下班了,明天说:)
#5
yaobao2013-01-16 16:44
  再见
#6
peach54602013-01-16 16:45
没区别...
#7
peach54602013-01-16 16:50
没什么不同。在声明一个 template type parameter(模板类型参数)的时候,class 和 typename 意味着完全相同的东西。一些程序员更喜欢在所有的时间都用 class,因为它更容易输入。其他人(包括我本人)更喜欢 typename,因为它暗示着这个参数不必要是一个 class type(类类型)。少数开发者在任何类型都被允许的时候使用 typename,而把 class 保留给仅接受 user-defined types(用户定义类型)的场合。但是从 C++ 的观点看,class 和 typename 在声明一个 template parameter(模板参数)时意味着完全相同的东西。

在声明 template parameters(模板参数)时,class 和 typename 是可互换的。
用 typename 去标识 nested dependent type names(嵌套依赖类型名),在 base class lists(基类列表)中或在一个 member initialization list(成员初始化列表)中作为一个 base class identifier(基类标识符)时除外。

这我也是第一次知道,受教育了...
#8
TonyDeng2013-01-16 17:59
模板,没有想象中的好用,很多顾忌的。简单的情况不妨用一下,复杂的,还是回避一下好,并非不用模板就写不出。C++的模板与C#的泛型不同,它仍然是在编译时生成每一份实际代码的,不是真的一份模板代码被所有类型共用(C++屡屡被人诟病臃肿就是这个东西造成的),C#的泛型才真的是那样。
#9
peach54602013-01-16 18:01
嗯.c++的模版是编译时处理的,所以需要在编译时推导出类型...
#10
zklhp2013-01-16 18:01
C++好复杂啊
#11
TonyDeng2013-01-16 18:07
C++确实是过于复杂,但关键在人,可以不用那些过于复杂的东西的。把C++和C适当结合起来,其实很好,只是门户观念严重的人,不屑这样,要搞纯种,那麻烦也是自己找的。之所以有这样的现实,就是C/C++的历史和源流太杂,连标准都是迁就习惯的,开始有点WEB标准那种尴尬了(虽然不至于那么严重)。在我看来,C#没有那样不统一的东西,反而好用,只是不屑.NET的人,又不愿意用。看自己的实践选择了。
#12
peach54602013-01-16 20:44
我很喜欢C++
但是我最初是搞C#的
现在让我回去C#我反而不习惯了,太憋屈了
#13
TonyDeng2013-01-16 22:16
我觉得差不多,C++有点繁琐,而且写GUI很不方便。
#14
peach54602013-01-17 08:17
我觉得C++很灵活
只要我很清楚我在做什么,就可以很好的掌控他
但是C#用得很憋屈...

举个例子
当我要去做某一件事,这件事可能分为abcd四个步骤
如果我很清楚abcd每件事都要做什么,怎么做...那么,我可以自己亲力亲为的做好...
但是如果这时候来了一个人,说我帮你做吧,你指挥我就行了,我反而觉得很不安全...
#15
rjsp2013-01-17 09:00
re TonyDeng:
“臃肿”只是因为没有分解好,随便举个例子,就拿链表来说,一切类型的链表存储都是相同的,跟类型无关,因此可以独立出来。而像构造、拷贝构造和析构,这些是不同的。因此只需要用模板浅浅的一封装就可以做到既易用,又无丝毫臃肿浪费。
相反,而像Java/.Net虽然现在也添加了模板支持,但性格天生不合,最为人诟病,所以它们更多的依赖“反射”而非模板

目前没有一个语言能容易的写好GUI,.Net也不例外。目前流行使用xml(比如qml)描述界面,但交互性就繁琐,有进步,但这种进步很小。而在VC平台上,.Net和C++的这种差别,只不过是M$故意为之。
对于GUI,我个人觉得M$的那套没前途,我比较看好 Qt 和 OpenGL ES
#16
TonyDeng2013-01-17 13:21
回复 15楼 rjsp
分解和封装不好造成的臃肿,是可以通过设计避免的,而模板针对实参类型生成每一份重复的代码的臃肿,是语言本身造成无法避免的,这是两回事。我说的是后者。C#的泛型是在JIT层实现参数类型代入的,那是它使用面向对象汇编的结果,不靠语言和编译器来实现,所以一份模板可以不用重复生成实际代码。反射模仿解释语言的面向未知数据类型,与泛型有区别,那个主要用于与COM交接数据。

.NET只是统一了接口而已,不存在与个别功能包竞争的问题。程序员不用学习太多各不相同的函数库,以及考虑它们的相容性,这本身就是最大的解放。WPF的核心是DirectX,渲染部分也是用非托管代码的,只是它封装出来的类库,我们不用再专门学DirectX了,贪图的是这个优势。

MS封装MFC,目的本来也是回避SDK的复杂性,但MFC的最终产品并不好,贪大求全,很多不必要的东西也集成在一个庞大的类中(MFC的特色就是一个类非常复杂),这东西本身就很臃肿,所以很多人说,宁愿返回用Win32 API直接开发,也不愿意使用MFC。MS重新设计了.NET,就是想抛弃MFC的那种状态的,.NET的类库简洁了许多,功能性非常接近Win32 API,但用起来没那么复杂。不过,MFC一时三刻还淘汰不了,当要写非托管GUI程序时,还得返回Win32 API或是MFC,但以我看来,Windows的未来版本将会逐步全面强制转向.NET框架,这是它的大战略。当然了,这是在选择使用Windows的情况下说,铁心不用的,就不用考虑这个问题了。

[ 本帖最后由 TonyDeng 于 2013-1-17 13:57 编辑 ]
#17
TonyDeng2013-01-17 13:26
回复 14楼 peach5460
那是你还没有过渡到面向对象的关系,仍然处于面向过程的思维。面向过程是控制所有动作和次序的,但面向对象是面向有个性行为的现实个体,换言之,前者面对死物,后者面对生物,难易程度当然不一样。你想象一下,在没有窗口的时候,你的程序控制着自己可以在什么时候结束,但有了窗口,你就无法限制用户点击右上角的关闭按钮关闭程序,这个时候面对的就是数据如何随时保存的问题,这在前者是基本不用考虑的。这是很大的差别。
#18
rjsp2013-01-17 14:29
回复 16楼 TonyDeng
谈其他语言会吵架,只谈C++吧

“而模板针对实参类型生成每一份重复的代码的臃肿,是语言本身造成无法避免的”
------ 模板很容易让人偷懒而导致代码膨胀,但不是说模板一定会令代码膨胀,相同的部分就不应该由模板实现,你可以看看“C++箴言:从模板中分离出参数无关的代码”,对于逻辑相同的代码,在C++模板中要求独立出去,通过void*和回调函数等手段避免重复。当然你也可以举个反例,能说明在C中可以不会引起代码膨胀,而在C++一定引起代码膨胀的例子。
#19
TonyDeng2013-01-17 14:46
不是这个意思的。模板定义的形参类型T,编译器在编译时会根据实际使用到这个模板的实参类型来创建不同的实现代码,比如实参类型是int,它就使用模板代码来生成一份int版的代码,再发现又有一个实参类型是double的,它又会多生成一份double的,你出现了多少种实参,它就创建多少份这样的代码。这个过程,就等于我们平时分开写int版和double版函数一样,只不过编译器代劳了而已,最终的机器码中,它确实与我们手工写的份量相同,有类同的代码。说的是这种臃肿。本来,代码可重用性的目的,就是避免代码重复,减少占用资源,C++的模板,在手工编码上确实是减少了劳动量,但最终的减少占用资源方面没有达到目的,只实现了一半。

其实这还不是大问题,模板最大的问题不在这里,而是在实参的不可预见性很容易出现“复制赋值”方面的错误,即模板代码使用了诸如比较、赋值等逻辑的时候,编译器事先是无法防止传入的实参对象没有实现那些功能的,而这样的做法,程序员很可能忽略这种陷阱,而按常规那样写。正如primer上面说的,写模板的技巧,足可以开一本新书,这就是过于复杂的事情了,初学的,还是先绕开这个东西为好。不使用模板,直接使用重载或多态性,也是很好的,我觉得这比模板还要清晰。

对的,在模板代码尽量少写与参数有关的代码,但很多时候某些逻辑代码未见得与参数类型无关,比如赋值和比较。像Compare这样常用的最适合使用模板的场合,都隐藏着实参类型的风险。这种错误,就如指针越界一样,再有经验的程序员也偶然会犯,但这种更麻烦,它更难调试和排查。

[ 本帖最后由 TonyDeng 于 2013-1-17 14:54 编辑 ]
#20
peach54602013-01-17 17:06
回复 17楼 TonyDeng
哦...上升到这么高层次了呀...

其实我的不习惯仅仅只是一些语言特性上的...
比如写for的时候,我想同步删除,c++的迭代器很方便...c#貌似还不好写
诸如像此类的一些语言特性让我不太习惯而已...呵呵...
你把高度整这么高,我有点无所适从了...

不过不可否认,c#,java之类的抽象层次更高,编程思想更为抽象,所以可以不用过多的关注底层...
某种程度上也算是解放了很多思想咯...
1