Boost源码剖析之:泛型编程精灵type_traits(rev#2).docVIP

Boost源码剖析之:泛型编程精灵type_traits(rev#2).doc

  1. 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Boost源码剖析之:泛型编程精灵type_traits(rev#2)

boost源码剖析之:泛型编程精灵type_traits 刘未鹏 C++的罗浮宫(/pongba) 动机使用traits的动机一般有三种,分派、效率、使某些代码通过编译。分派 下面有一个模板函数,假设一个动物收容组织提供了它,他们接受所有无家可归的可怜的小动物,于是他们向外界提供了一个函数接受注册。函数看起来像这样:templateclass T // T表示接受的是何种动物 void AcceptAnimals(T animal) {... //do something }; 但是,如果他们想将猫和狗分开处理(毕竟饲养一只猫和饲养一只狗并不相同。他们可能会为狗买一根链子,而温顺的猫则可能不需要)。一个可行的方法是分别提供两个函数:AcceptDog和AcceptCat,然而这种解决办法并不优雅(想想看,注册者可能既有一只猫又有一只狗,这样他不得不调用不同的函数来注册,而且,如果种类还在增多呢,那样会导致向外提供的接口的增多,注册者因此而不得不记住那些烦琐的名字,而这显然没有只需记住AccpetAnimal这一个名字简单)。如果想保持这个模板函数,并将它作为向外界提供的唯一接口,则我们需要某种方式来获取类型T的特征(trait),并按照不同的特征来采用不同的策略。这里我们有第二个解决办法:约定所有的动物类(如class Cat,class Dog)都必须在内部typedef一个表明自己身份的类型,作为标识的类型如下:struct cat_tag{}; //这只是个空类,目的是激发函数重载,后面会解释 struct dog_tag{}; //同上于是,所有狗类都必须像这样:class Dog { public: // 类型(身份)标志,表示这是狗类,如果是猫类则为typedef cat_tag type;typedef dog_tag type; ... } 然后,动物收容组织可以在内部提供对猫狗分开处理的函数,像这样:// 第二个参数为无名参数,只是为了激发函数重载templateclass T void Accept(T dog,dog_tag) {...} templateclass T void Accpet(T cat,cat_tag) // 同上 {...}于是先前的Accept函数可以改写如下:templateclass T void Accept(T animal) //这是向外界提供的唯一接口 {// 如果T为狗类,则typename T::type就是dog_tag,那么typename T::type()就是创建了一个dog_tag类的临时对象,根据函数重载的规则,这将调用Accept(T,dog_tag),这正是转向处理狗的策略如果T为猫类,则typename T::type为cat_tag,由上面的推导,这将调用Accept(T,cat_tag),转向处理猫的策略typename 关键字告诉编译器T::type是个类型而不是静态成员Accept(animal, typename T::type()); // #1 } 所有类型推导,函数重载,都在编译期完成,你几乎不用耗费任何运行期成本(除了创建dog_tag,cat_tag临时对象的成本,然而经过编译器的优化,这种成本可能也会消失)就拥有了可读性和可维护性高的代码。“但是,等等!”你说:“traits在哪?”,typename T::type其实就是traits,只不过少了一层封装而已,如果像这样作一些改进:templatetypename T struct AnimalTraits { typedef T::type type; }; 于是,#1处的代码可以写成Accept(animal, typename AnimalTraitsT::type()); 效率 通常为了提高效率,为某种情况采取特殊的措施是必要的,例如STL里面的copy,原型像这样:// 将[first,last)区间内的元素拷贝到以dest开始的地方templatetypename IterIn,typename IterOut IterOut copy(IterIn first,IterIn last,IterOut dest){ // ptr_category用来萃取出迭代器的类别以进行适当程度的优化return copy_opt(first,last,dest, ptr_category(first,dest)); } copy_opt有两个版本,其中一个是针对如基本类型的数组作优化的,如果拷贝发生在char数组间,那么根本用不着挨个元素赋值,基于数组在内存中分布的连续性,可以用速度极快的memmove函数来完成。ptr_category有很多重载

文档评论(0)

yan698698 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档