篮子、水果和鸡蛋——关于C++的模板偏特化和萃取编程技法

篮子里拿鸡蛋问题 一个一个拿,正好拿完。两个两个拿,还剩一个。三个三个拿,正好拿完。 四个四个拿,还剩一个。五个五个拿,还差一个。六个六个拿,还剩三个。 七个七个拿,正好拿完。八个八个拿,还剩一个。九个九个拿,正好拿完。 思路: 7*9=63; 五个五个拿,还剩一个。所以个位数是4/9; 又因为两个两个拿,还剩一个。所以个位数是9; #include<bits/stdc++.h> using namespace std; int main() { int i = 3; int x = 0; 阅读详情

最近在读《STL源码剖析》。读这本书的时候发现自己的C++的知识其实是非常匮乏的。 从大学的C++教材上学到一些C++基本的语法、内存管理、继承、多态等方面的基础知识。这些只是是一棵大树的根。而读STL的源码和侯捷的解析的时候,发现C++还有很多丰富的细节和技巧。这些是大树上的枝叶。学习C++,不仅要学习根,也要学习枝叶,这样才能让大树茂盛起来。虽然C++语法一些用法较为晦涩,但读完这些代码之后觉得思路比以前更开阔,另外可以活动脑筋。

比如模板的偏特化这个特性。侯捷的《STL源码剖析》中对于模板的偏特化(partial specialization)的解释为: 如果class template拥有一个以上的template参数,我们可以针对其中某个或多个 template参数进行特化工作。template是一个很抽象的东西。template偏特化之后就让模板变得具体那么一点点。

用一个形象一点的比喻吧。我们把template比作一个装东西的篮子。这个篮子既可以装鸡蛋,也可以装苹果。那么所谓偏特化就是让你用一个篮子专门装水果,这就是template水果篮。以后你就只能使用水果篮来装苹果、装梨,而不能使用其他的篮子来装这些水果了。

看一个STL例子:

有一个“篮子” iterator_traits, 它内部typedef 了value_type类型,用来定义模板的参数类型class I 的value_type。

1template<classI>
2struct iterator_traits
3{
4    typedeftypename I::value_type value_type;
5};
如果用一般的STL的iterator类型去实例化这个模板的时候是不会有问题的,因为STL内建的iterator里typedef了value_type。但是如果用原生指针去实例化这个模板就悲剧了。因为原生指针可没有办法typedef什么东西。如果把iterator比作鸡蛋,把原生指针比作水果,那么这个篮子就只能装鸡蛋而不能装水果。如果必须要装水果,怎么办?


办法就是用模板的偏特化,给水果专门做一个水果篮了。看下面的代码

1template <class T>
2struct iterator_traits<T*>
3{
4typedef T value_type;
5}

当用原生指针T*去实例化iterator_traits模板的时候,就会调用上面的代码把类型T typedef为value_type。这就相当于给iterator_traits实现了一个特别的版本专门处理原生指针。也就是说,水果篮做好了:)

如果理解了模板的偏特化, 就理解了萃取编程技法的一大半了。什么是萃取编程技法呢? 萃取来自于英语的traits, traits的意思是特性、特点。萃取编程技法实际上就是利用模板的偏特化,充分的萃取不同型别的特点。

还是拿鸡蛋、水果和篮子做例子。别看装鸡蛋、水果都用篮子,但是装鸡蛋的篮子和装水果的篮子能一样吗? 装鸡蛋的篮子一定要抗摔防震。因为鸡蛋壳很脆一碰就破。而装水果的篮子则要美观好看。因为水果篮一般都用作送给别人的礼物。

还是用上面的iterator_traits 这个篮子做例子,看下面的代码。

01template<classI>
02struct iterator_traits
03{
04    typedeftypename I::value_type value_type;
05}; //泛化版本
06 
07template<classI>
08struct iterator_traits<T*>
09{
10    typedefT value_type;
11}; //偏特化版本

我们给这个iterator_traits设计了两个版本。上面的是泛化的版本,下面的是为原生指针偏特化的版本。

如何使用iterator_traits这个篮子呢,看下面这个模板函数:

1template <class I>
2typename iterator_traits<I>::value_type
3func(I ite)
4{
5    return*ite;
6}

这个模板函数以一个class I作为类型参数, 函数的参数为一个class I类型的对象, 返回的是class I对象提领的对象。函数的返回值类型定义就使用了萃取编程的技法。我们看函数返回值的定义:

1iterator_traits<I>

这个模板就是上文中我们定义的篮子。在上文中我们针对不同类型的特点,实现了两种将template的实例化的方法:实现了用STL的iterator去实例化这个模板的方法,也实现了用原生指针去实例化这个模板的方法。因为我们“因材施教”的调用了不同的代码,才把水果放在了水果篮里,把鸡蛋放在其他的篮子里。这就是萃取的编程技法。


C++的语法是很艰深的。STL对于C++的使用也可以说是很有“创造性”。 因为这种“创造性”,给我们阅读STL源码的时候造成了一定的困难,不过也是因为这种“创造性” , 让我们使用STL的时候非常的轻松和愉快。哎,这就是所谓的“痛并且快乐着”的那种感觉吧。


STL学习心得:

  http://daoluan.net/blog/tag/%E3%80%8Astl%E6%BA%90%E7%A0%81%E5%89%96%E6%9E%90%E3%80%8B/

C++ 模板特化与偏特化 文章目录1.模板特化1.1 概述1.2 函数模板特化1.3 类模板特化2.模板偏特化2.1 概述2.2 函数模板偏特化2.3 类模板偏特化3.模板类调用优先级参考文献 1.模板特化 1.1 概述 模板特化(template specialization)不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板特化。模板特化有时也称之为模板的具体化,分别有函数模板特化模板特化。 1.2 函数模板特化 函数模板特化指函数模板模板参数为特定类型下的特定实现。查看以下示例: #include <i 阅读详情

相关推荐

C++模板的特化(specialization)偏特化(partial specialization)

C++模板的特化及偏特化模板全特化:对类中的某个成员函数进行特化处理类模板偏特化范围偏特化函数模板全特化:函数模板偏特化模板函数模板类有的时候可能需要对传入的不同类型进行不同的处理,比如说有的模板传入int或double类型都可以处理,但是传入char型则会出错,这时就需要模板特化的方式。 类模板全特化: 全特化即将模板类型里的所有类型参数全部具体指明之后处理,如下 template<typena

weixin_43744293的博客 1万+

分享:篮子水果鸡蛋——关于C++模板偏特化萃取编程技法

分享:篮子水果鸡蛋——关于C++模板偏特化萃取编程技法 篮子水果鸡蛋——关于C++模板偏特化萃取编程技法 http://my.oschina.net/costaxu/blog/97691 ...

107

C++模板全特化,偏特化(局部特化)

全特化,所有TU类型模板参数,都得用具体的类型代表。原来T 现在T* (从任意类型T缩小为指针类型T*)。特化:对特殊的类型,进行特殊的对待。给他开小灶,给他写适合他的专用代码,必须现有泛化版本,才能有特化版本。留一个模板类型参数,留下U,另外两个绑定到具体类型,所以只剩下U。因为我们特化了double double类型的testfunc函数 所以我们调用的时特化的testfunc函数。当T U这两个类型模板参数都为int 类型时。偏特化从两个方面说起,一个是从模板参数数量上,一个是从模板参数的范围上。

qq_42508660的博客 1095

C++——模板特化偏特化

1.引言C++中的模板分为类模板函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现。目前,STL在C++社区中得到了广泛的关注、应用研究。理解掌握模板是学习、应用研究以及扩充STL的基础。而STL模板实例中又充斥着大量的模板特化偏特化。2.模板的定义(1) 类模板定义一个栈的类模板,它可以用来容纳不同的数据类型说明如下:template class stack {private:  list* top;public:  stack();  st

shineHoo的专栏 1万+

C++模板特化示例总结

类型参数特化为具体类型。非类型参数,值参数,特化为具体数值。模板参数列表定义在template关键字后中,特化参数列表定义在模板名称(类名或函数名)后的中。对于特化的模板模板参数列表中去掉特化的参数。在类定义或者函数定义中,用特化的类型名替换对应的通用类型参数名,用具体的特化值,替换对应的非类型参数名。特化的通用类型非类型参数名,不再有效。

yinminsumeng的博客 1061

C++模板的特化

详解C++模板的特化(函数模板特化、类模板特化)

2301_76197086的博客 1375

C++ 模板进阶(模板的特化)

这里我们再次学习模板,这次是进阶模板,要比上次所学的模板更深一些,包括非类型模板参数以及函数模板的特化、类模板的全特化、偏特化等。

冰果滴的博客 2160

C++模板特化与偏特化

模板特化技术如同手术刀般精准,赋予开发者针对特定类型定制行为的能力。通过合理运用全特化与偏特化,我们可以在保持泛型代码优雅性的同时,实现关键路径的性能优化。掌握这一技术需要注意理论理解与实践经验的平衡,正如C++之父Bjarne Stroustrup所言:"C++的设计原则是你不为你不需要的东西付出代价"。模板特化正是这一哲学的完美体现。

llookl的博客 898

C++中的模板特化偏特化

然后进行了偏特化,当 T1 为 int 类型时,新的 Pair 类有一个额外的成员函数 multiply ,用于计算 first second 的乘积。然后针对 bool 类型进行了完全特化,在完全特化的类中可以提供与通用模板不同的实现,比如更高效的存储方式或者特殊的操作方法,以适应 bool 类型的特点。然后对 bool 类型且大小为10的栈进行了完全特化,在特化版本中重新定义了 push pop 等成员函数的具体实现。这种偏特化可以针对特定类型组合进行特殊的处理,以满足不同的需求。

2401_88249494的博客 1259

C++模板特化

C++模板特化详解

myscratch的博客 1596

C++ 模板偏特化

From: http://blog.sina.com.cn/s/blog_65d069c601010fb2.html c++模板特化 一、模板特化, specialization oftemplate 模板特化(specialization oftemplate)并不是说实例化一个模板,如template ,classstack;声明stack,这是实例化一个模板类。类模板特化的意思是,

fyfcauc的专栏 697

C++模板全特化(具体化)与偏特化(部分具体化)详解

1.模板简介 模板就是实现代码重用的一种机制,它可以实现类型参数化,即把类型定义为参数, 从而实现了真正的代码可重用性。 模板编程函数重载可以实现C++静态多态,也叫编译时多态。 模版可以分为两类,一个是函数模版,另一个是类模版。 2.模板特化的目的 模板本来是一组通用逻辑的实现,但是可能存在特定的参数类型下,通用的逻辑实现不能满足要求,这时就需要针对这些特殊的类型,而实现一个特例模板—即模板特化。 3.重点注意 1)类模板函数模板都可以被全特化; 2)类模板偏特化,不能被重载;...

MaxMaxXiong的博客 6419

C++_模板的特化

大多数情况下模板可以解决许多重复性工作,因为把不同的类型传给模板参数后,编译器就会自动生成该类型的函数或类,但是如果传给模板参数的类型是特殊类型(比如:指针类型),那么最终的结果可能会有所偏差,原因就是该模板的内容实现逻辑是按照普通类型的实现逻辑进行的。这时候如果传指针类型给到该模板,则需要先对指针进行解引用后才能走普通类型的实现逻辑,如果直接对指针本身进行操作则结果会发生错误。

安权_code的博客 1905

C++模板偏特化与全特化

C++模板的全特化与偏特化 一、为什么要特化模板 模板为什么要特化,因为编译器认为,对于特定的类型,如果你能对某一功能更好的实现,那么就该听你的。 二、全特化与偏特化 模板分为类模板与函数模板,特化分为全特化与偏特化。 全特化就是限定死模板实现的具体类型。 偏特化就是如果这个模板有多个类型,那么只限定其中的一部分。 例子: 全特化 teplate<> class A<int, double>() {...}; 偏特化 temp

lial13的博客 863

C++模板特化、偏特化

  模板分为函数模板模板,特化分为全特化偏特化。使用模板的时候,我们的目的就是希望可以不用每个类型实现一遍,而是用一个模板代替这个类型。如果所有类型的实现都是一个统一的一样的实现,就不需要模板特化或者偏特化了,但是大多数情况是肯定有特殊版本需要特殊处理的,下边用两个典型的例子记录一下: 1、hash<_Kty>:模板全特化 2、vector<bool>:模板偏特化 一...

Bob__yuan的博客 2663

C++ 模板模板全特化、模板偏特化

C++ 模板模板全特化、模板偏特化

renbenliu的博客 1568
上一篇: linux后台开发必看书
下一篇: 那些年·我们读过的专业书籍
markman101
博客等级 码龄19年 199粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值