STL中的Traits编程技法
最近在看读《STL源码剖析》,看到Traits编程技法这节时,不禁感慨STL源码作者的创新能力。那么什么是Traits编程技法呢?且听我娓娓道来:
我们知道容器的许多操作都是通过迭代器展开的。其中容器类似于数组,迭代器类似于指针。我们用数组来写个例子:
int arr[] = {,,,,};
int *p;
p = &arr[];
假设,我将第1、2遮挡起来,问你p所指向的对象arr[2]是什么类型,你恐怕无法回答。因为它可以是int,char,float甚至你自己定义的类型。假设我们现在是个容器:
list<int> lit(,);
list<int>::iterator it1,it2;
it1 = lit.begin();
it2 = lit.end();
其中lit是个容器对象,it1和it2都是容器的迭代器。假设现在有个函数,他接受两个迭代器作为参数,并且返回类型是迭代器所指的类型:
template<class iterator>
返回类型
fun(iterator first,iterator last)
{
//函数体
}
问题来了,现在我的返回类型假设是iterator所指向的类型。我们无法进行下去了。。。别怕,我们接着往下看:
如果我们将迭代器定义成一个类:
template<class T>
class My_iterator
{
public:
T* ptr;
typedef T value_type;
My_iterator(T* p = ):ptr(p){}
//...
};
也就是说如果我们的list的迭代器的类型也是上面那种形式,那么我们的fun函数就可以这样写了:
template<class iterator>
typename iterator::value_type //返回类型
fun(iterator first,iterator last)
{
//函数体
}
这样,迭代器所指的容器元素的类型就可以取出来了。怎么样,是不是很cool!但是不是所有的迭代器都是一个类啊,比如我们的原生指针也是迭代器的一种。vector的迭代器就是原生指针。那么用上面的那种方法似乎就不行了。但是STL的编写者创造了一个很好的方法---迭代器类型萃取模板,可以萃取原生指针所指向的元素的类型。对了,什么是原生指针?就是那种真正的是一个指针,我们的许多容器(list,deque)的迭代器是模拟指针但实际上它不是真正意义上的指针,他是一个类里面封装了原生指针。上面的My_iterator是迭代器,My_iterator里面的成员ptr就是原生指针。现在,是Traits编程技法发挥作用的时候了:
如果我们有个迭代器类型萃取模板,如下:
template<clas iterator> //专门用来萃取迭代器iterator指向的元素的类型
class My_iterator_traits
{
typedef typename iterator::value_type value_type;
//...
};
于是,我们的fun()函数就可以写成这样:
template<class iterator>
typename My_iterator_traits<iterator>::value_type //返回类新
fun(iterator first,iterator last)
{
//函数体
}
明眼人一眼就能看出这个代码跟原来的相比除了多一层包装,好像什么实质意义也没有,别急。我们这样写并不是做无用功,是为了应付上面说的原生指针而设计的。这时,我们的偏特化要派上用场了,针对原生指针的迭代器类型萃取偏特化模板如下:
template<clas iterator> //专门用来萃取迭代器iterator指向的类型的
class My_iterator_traits<iterator*>
{
//typedef typename iterator::value_type value_type;
typedef T value_type; //注意与上面的区别
//...
};
怎么样,这样一个迭代器类型萃取模板就这样诞生了。它可以萃取自定义的iterator类型和原生指针类型。但是,请注意了:在萃取自定义的iterator的时候这样写:
typedef typename iterator::value_type value_type;所以我们自定义的迭代器都应该定义时都应该有typedef T value_type.否则,你的迭代器就不能被正确萃取。STL的迭代器在定义的时候也是有类似的限制的!
STL中的Traits编程技法的更多相关文章
- STL——迭代器与traits编程技法
一.迭代器 1. 迭代器设计思维——STL关键所在 在<Design Patterns>一书中对iterator模式定义如下:提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素 ...
- 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法
大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...
- [转]Traits 编程技法+模板偏特化+template参数推导+内嵌型别编程技巧
STL中,traits编程技法得到了很大的应用,了解这个,才能一窥STL奥妙所在. 先将自己所理解的记录如下: Traits技术可以用来获得一个 类型 的相关信息的. 首先假如有以下一个泛型的迭代器类 ...
- STL源码--iterator和traits编程技法
第一部分 iterator学习 STL iterators定义: 提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式. 任何iteartor都应该提供5 ...
- STL源码分析读书笔记--第三章--迭代器(iterator)概念与traits编程技法
1.准备知识 typename用法 用法1:等效于模板编程中的class 用法2:用于显式地告诉编译器接下来的名称是类型名,对于这个区分,下面的参考链接中说得好,如果编译器不知道 T::bar 是类型 ...
- STL Traits编程技法
traits编程技法大量运用于STL实现中.通过它在一定程度上弥补了C++不是强型别语言的遗憾,增强了C++关于型别认证方面的能力. traits编程技法是利用“内嵌型别”的编程技法和编译器的temp ...
- STL源码之traits编程技法
摘要 主要讨论如何获取迭代器相应型别.使用迭代器时,很可能用到其型别,若需要声明某个迭代器所指对象的型别的变量,该如何解决.方法如下: function template的参数推导机制 例如: tem ...
- STL源码剖析——iterators与trait编程#2 Traits编程技法
在算法中运用迭代器时,很可能用到其相应类型.什么是相应类型?迭代器所指对象的类型便是其中一个.我曾有一个错误的理解,那就是认为相应类型就是迭代器所指对象的类型,其实不然,相应类型是一个大的类别,迭代器 ...
- STL之traits编程技法
traits编程技法利用了“内嵌型别”的编程技巧与编译器的template参数推导功能. 下面主要看看利用traits编程技法实现的迭代器萃取机制. 5种迭代器类型定义: struct input_i ...
随机推荐
- navigation的pushViewController卡顿问题
问题:在ios中一个viewController中,添加下面代码: <pre name="code" class="objc">UIViewCont ...
- ios-点击屏幕,隐藏键盘
ios-点击屏幕,隐藏键盘 - (void)getFirstRegist{ //结束键盘编辑 __weak typeof(self)weakSelf = self; UITapGestureRecog ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之二
/** ****************************************************************************** * @author 暴走的小 ...
- hadoop2集群中的datanode启动以后自动关闭的问题
今天在启动前几天搭建成功的hadoop集群的时候,出现了datanode启动之后自动关闭的情况,经过查询之后发现问题产生的原因是:在第一次格式化dfs后,启动并使用了hadoop,后来又重新执行了格式 ...
- Axiom3D学习日记 5.Frame Listeners, and Input Handling
Frame Listeners In Ogre's C++, we would register a class to receive notification before and after a ...
- Quartz.NET配置(Log4net)
最近有个任务关于服务调度,想起以前看过Quartz.NET调度任务非常棒. 今天小试Quartz.NET,前面配置Quartz.NET很轻松,控制台也输出了.但是想配合Log4net来做日志文件,怎么 ...
- jQuery AJAX实现调用页面后台方法
1.新建demo.aspx页面.2.首先在该页面的后台文件demos.aspx.cs中添加引用. using System.Web.Services; 3.无参数的方法调用. 大家注意了,这个版本不能 ...
- [转帖]vivado & VS2013工具
来源:http://bbs.csdn.net/topics/380057699 添加OpenCV库后,MFC在Debug模式下调试,提示应用程序无法正常启动(0xc000007b). 解决方法:在环境 ...
- .NET 4.6
http://referencesource.microsoft.com/ DownLoad 下载原代码
- [总结]FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...