`
61party
  • 浏览: 1122989 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

.NET Generics vs. C++ Templates

阅读更多

.NET Generics VS C++ Templates

刘未鹏 /

C++的罗浮宫(http://blog.csdn.net/pongba)

C++中还没有引进模板的时候,C++STL之父stepanov就敏锐的发觉,面向对象理论并不能描述现有的所有结构,比如,算法就不是一个对象,再深入下去,他发觉有很多算法的抽象逻辑并不依赖于它所作用的对象以及底层数据结构的组织方式,也就是说,算法的逻辑可以抽象出来单独描述,于是他试图用当时的C++来描述这种抽象,而在当时,C++还不支持泛型,结果导致这种对算法抽象描述非常繁复而低效,与此类似的结构还有容器(算法和容器是STL的两大组成部分,两者通过迭代器“粘合”起来)。后来C++中加入了模板,不得不说很大程度上是stepanov努力的结果。这种想法在当时面向对象理论正一手遮天的情况下不得不用“天才”来形容,它直接影响了C++的“后半生”。

泛型可以在几乎无损于效率的情况下支持代码的高度可复用性,并且具有数学的抽象美(这一点接触过STL源码的人都非常清楚)。于是,泛型几乎立即就成了C++中举足轻重的特性之一。

而现在,.NETjava也意识到泛型的重要性——尽管它们有单根的特性,但是,基于继承的算法抽象描述注定是“强绑定”的,低效的,面向对象的多态的额外负担在此无可逃避。但是,基于泛型的算法抽象描述却是“非绑定”的,高效的,任何符合语法和语义要求的对象都可以作为参数传递给它,泛型的本质就是为每一种对象生成一份单独的代码(也就是所谓的“实例化”),这一份量身顶做的代码具有很高的效率,是强类型的,不需要运行期多态的支持和负担,所以.NETjava中引入泛型可以说是顺理成章的。只不过,由于.NETjava的语言本质(解释型),所以其中的泛型不能像C++那样淋漓尽致,有一些很难逾越的技术鸿沟,这在下面会提到。

下面就来说说.NET中的泛型实现。至于其语法是次要的,对C++模板稍有了解的人不难从几行示例代码中看出来。

其实,泛型的实质是相当简洁和直观的,了解宏的人很清楚,在除去类型安全的前提下,一些简单的泛型代码可以用宏来模拟。这也就是说,编译器负责为用户提供的每一集模板参数实例化出一份模板的实体。

也许你会说,这不是和C++的几乎一样吗?是的,思想是一样的,但是,实现却有本质的不同。

.NET的泛型代码的实例化是在运行期进行的,这一点与C++有本质上的不同。在.NET泛型中,处在编译期的只是一个简单的引用,而对相应的类的实例化在运行期由CLR运行层来进行,所以.NET泛型是平台的一部分,而不像C++那样,是编译器的一部分。

在运行期由CLR进行的实例化给.NET泛型带来一个显著的好处:避免代码膨胀。在C++中,位于两个不同编译单元中的模板实例化很可能导致两份完全相同的代码,而且,由两集不同模板参数实例化出来的模板实例可能无法共享某些代码。但是.NET中,实例化时CLR知道一切,所以不会出现在两个Assembly中出现两份相同的实例化代码的情况,并且,一个Assembly中实例化的代码可以被用于另一个Assembly,甚至同一个模板的不同实例间也可以共享某些代码。这种代码共享的特点可以某程度上缓解代码膨胀。

但是,.NET的泛型也有一些弱点。在运行期实例化的特点决定了它无法进行某些复杂的类型推导(这将导致JIT速度缓慢),也就是说,像STLBoost库中广泛运用的traits技术在.NET中注定要嗑磕碰碰。而支持复杂的类型推导技术的语言特性是偏特化,这也就解释了为什么.NET目前还没有支持偏特化的原因(甚至连特化也不支持)。但是,traits却又是精巧的架构和效率所必须的[1]。所以,在(运行期)效率上,.NET无法与C++比肩。

另外,.NET泛型支持constraint(约束),所谓constraint,就是给模板形参加上约束。在.NET中这些约束主要是诸如:继承自某个基类,实现了哪些接口,以及是否含有无参的public构造函数。在.NET中引入约束是有理由的:如果不引入约束,则有两种情况:第一,对于某些模板实参,实例化代码不能通过JIT编译,又因为泛型代码的编译是在运行期由CLR运行层进行的,所以彼时的编译错误可能得通过异常的方式来反映[2],然而更重要的是,这可能导致很多无谓的编译时耗,也就是说,CLR可能在编译了许多代码后发现一个编译错误,于是以前的编译都是在浪费时间。第二,解决第一种情况的方法是强制转换,例如,如果你想要对某个对象(该对象的类型是模板形参)调用CompareTo,你得先把该对象转换为ICompareable接口。这虽然能够解决问题,但是又增加了不必要的运行时开销。所以C#采用constraint,这样,如果形参不符合要求(例如,没有特定的成员函数),则在编译期就能够发现,既保证了编译期的强类型检查,又减小了运行期开销。作为比较,C++并不支持constraint,至于原因StroustrupD&E里说的很清楚。C++并不存在上面所说的问题,并且C++中的constraint可以通过其它方式来模拟[3]

从总体上来说,.NETC++“道不同”,层次也不一样,.NET中的泛型有这些简单的特性对于它已经够用了,因为.NET在运行期的信息远比C++要多(再加上单根继承的优势),所以一些工作可以交给运行期的类型识别或reflection来做(不用在编译期进行复杂的类型推导),并且.NET的语言特性相对少而简洁,这就避免了一些繁杂的工作。而C++作为编译型的语言,一经编译便几乎丧失所有结构信息和类型信息(typeinfo只包含了相当少的一部分信息),所以,C++必须在编译期打点好一切,从而,C++模板的众多特性是不可忽缺的。读者不妨将.NETdelegateBoost库中的boost::signal对比一下,看看后者为了实现一个完善的“回调”系统做了多少工作。而前者有单根结构和reflection的支持,其实现要简单得多。

所以,.NET泛型虽然简单,但却是量身定做,而C++泛型虽然复杂,却精巧而必要。二者各取所需,在各自的语言中都会有大量的用武之地。至于孰优孰劣是语言专家的事情,这里的对比是想让读者对两者有个大体的把握和理性的认识。



[1] traits的作用某中程度上意味着“类型信息的传递”以及“对于哪些类型做哪些对应的事”,这对于一个健壮的编译期类型判别系统是必须的。

[2] 事实上,假设这种存在这种情况,那么CLR抛出的异常将无法被用户catch,除非将对模板的使用放在异常try块里——这显然是不友好的。

[3] 有兴趣的读者可以参考boost库里面的相关部分。C++的这种方式可以避免增加语言特性的集合,避免过多的关键字。

分享到:
评论

相关推荐

    C++\CLI学习\pdf

    C++/CLI 是一种特殊的 C++ 扩展,旨在帮助开发者将现有的 C++ 代码集成到 .NET 平台上,而无需重写应用程序。这种集成方式不仅能够充分利用现有的 C++ 资产,还能够让开发者利用 .NET 框架的强大功能。 #### 二、...

    TMS FlexCel Studio v6.3.0.0 Full Source

    ApiMate tool for automatically showing needed Delphi/C++ code for generating specific .XLS/.XLSX file cells with Flexcel Templates can be embedded inside your exe. No additional files to distribute ...

    li_3ck_02a_1118.pdf

    li_3ck_02a_1118

    基于MATLAB的牛顿迭代法实现

    基于MATLAB的牛顿迭代法实现

    mellitz_3ck_01_0319.pdf

    mellitz_3ck_01_0319

    2025探索银行业人工智能驱动技术转型的投资回报率

    内容概要:文章阐述了银行采用人工智能(AI)技术替代传统系统的紧迫性和收益,讨论了通过构建现代化的数据和技术平台实现效率提升的方法,同时强调实施过程中确保数据质量和建立信任的重要性。文中提及,在金融行业中,若想优化业绩则必须拥抱AI带来的机遇,并为此进行经营模式的革新。根据Workday主办的研讨会内容,PwC金融服务风险与监管领导和Workday金融服务高层指出了大部分银行对AI认知不足的问题,强调AI在金融、人力资源以及IT等领域的广泛应用潜力及具体应用场景,如欺诈检测、技能映射和财务管理方面的作用。并且提到了AI部署过程中可能出现的技术与非技术难题及相应解决办法,鼓励金融机构及时投资建设新型基础设施,以保持竞争力。 适用人群:银行及其他金融机构管理人员;金融科技领域的专业研究人员;对企业数字化和智能化转型感兴趣的商业分析师、投资者;从事信息技术咨询工作的顾问。 使用场景及目标:本文可以帮助金融机构制定合理的技术发展战略规划,评估是否有必要推进AI技术转型,同时也为希望涉足银行科技项目的开发者提供了宝贵的市场洞察,帮助理解行业内普遍存在的困难与潜在的市场需求。此外,对于想要了解银行

    matlab程序代码项目案例论文+程序 基于在线优化的快速模型预测控制Fast model predicitive control with matlab interface.zip

    matlab程序代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_043071]Phase Manager and a Scalable Batching Solution.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_044386]1769-SM2 Compact I-O to DSI Module - Multi Drive Mode Operation - with.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_041232]Monitor I-O Connections in Logix.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    chromedriver-linux64-136.0.7058.0.zip

    chromedriver-linux64-136.0.7058.0.zip

    [AB PLC例程源码][MMS_042504]Logix5000 interface to Atlas-Copco Tool Controller over EtherNet-IP.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    [AB PLC例程源码][MMS_042349]How to read-write data to-from a PLC using OPC in Visual Basic 6.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    电力工程领域中背压热电联产电厂的设计与参数计算

    内容概要:本文档介绍了背压热电联产(CHP)发电厂的详细设计步骤,涵盖确定各状态点的压力、温度、比焓以及质量流率的具体方法。主要内容围绕计算净电功率、燃料消耗及其效率展开,并提供了T-s图绘制的指南。针对每个组件(如蒸汽轮机、冷凝器、除氧器等),都列出了详细的效率假设和压力损失表,为实际工程应用提供了宝贵的参考资料和操作指导。同时,该作业任务要求学生从给定初始值中选择合适的操作条件进行系统模拟,并利用课程讲义和Moodle平台资料完成计算流程。 适用人群:对能源转换和动力设备设计感兴趣的学生或者初涉该领域的工程师。 使用场景及目标:旨在帮助学员深入了解并掌握背压热电联产装置的工作原理和技术指标计算的方法论,通过实践练习提高他们的问题解决能力。 其他说明:文档强调了稳态运行假设的重要性,即物质平衡等于能量输入等于输出的原则,并鼓励参与者借助附录提供的典型操作参数图表来寻找解决问题的方向。此外,它还特别指出对于一些变量值求解可能需要迭代法来进行调整,直至获得稳定结果。提交的报告必须含有一份详细的T-s图和其他必要附件。

    机器学习-市财政收入分析(含数据集)

    机器学习_市财政收入分析(含数据集)

    [AB PLC例程源码][MMS_046989]KAT with Code Sequencer.zip

    AB PLC例程代码项目案例 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!

    tracy_3cd_01_0318.pdf

    tracy_3cd_01_0318

    lusted_3cd_01_0918.pdf

    lusted_3cd_01_0918

    基于51的自动分拣系统设计20250307

    题目:基于51的自动分拣系统设计 主控:AT89C52 测距模块:超声波测距模块 甲醛传感器(ADC0832+滑动变阻器模拟) 粉尘传感器(PCF8591+滑动变阻器模拟) 净化模块(继电器驱动蓝灯) 排风模块(继电器驱动绿灯) 电源电路(5V降压为3.3V供电) 显示模块(LCD1602) 声光报警 按键(3个,切换阈值选择,阈值加减) 检测物体:开关模拟 电机驱动模块(继电器驱动直流电机转动) 功能: 1.显示屏显示甲醛,粉尘浓度可以切换设置阈值。 2.通过甲醛传感器检测车间环境,大于阈值时声光报警并启动净化模块。 3.通过粉尘传感器检测车间环境,大于阈值时声光报警并启动排风模块。 4.采用超声波传感器进行物体超高监测异常(大于XX距离)时触发声光报警 5.检测到物体(开关闭合)直流电机转动(模拟传送带)

    network-server

    network_server

Global site tag (gtag.js) - Google Analytics