最近在看读《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编程技法的更多相关文章

  1. STL——迭代器与traits编程技法

    一.迭代器 1. 迭代器设计思维——STL关键所在 在<Design Patterns>一书中对iterator模式定义如下:提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素 ...

  2. 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法

    大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...

  3. [转]Traits 编程技法+模板偏特化+template参数推导+内嵌型别编程技巧

    STL中,traits编程技法得到了很大的应用,了解这个,才能一窥STL奥妙所在. 先将自己所理解的记录如下: Traits技术可以用来获得一个 类型 的相关信息的. 首先假如有以下一个泛型的迭代器类 ...

  4. STL源码--iterator和traits编程技法

    第一部分 iterator学习 STL iterators定义: 提供一种方法,使之能够依序巡访某个聚合物(容器)所含的各个元素,而又无需暴露该聚合物的内部表达方式. 任何iteartor都应该提供5 ...

  5. STL源码分析读书笔记--第三章--迭代器(iterator)概念与traits编程技法

    1.准备知识 typename用法 用法1:等效于模板编程中的class 用法2:用于显式地告诉编译器接下来的名称是类型名,对于这个区分,下面的参考链接中说得好,如果编译器不知道 T::bar 是类型 ...

  6. STL Traits编程技法

    traits编程技法大量运用于STL实现中.通过它在一定程度上弥补了C++不是强型别语言的遗憾,增强了C++关于型别认证方面的能力. traits编程技法是利用“内嵌型别”的编程技法和编译器的temp ...

  7. STL源码之traits编程技法

    摘要 主要讨论如何获取迭代器相应型别.使用迭代器时,很可能用到其型别,若需要声明某个迭代器所指对象的型别的变量,该如何解决.方法如下: function template的参数推导机制 例如: tem ...

  8. STL源码剖析——iterators与trait编程#2 Traits编程技法

    在算法中运用迭代器时,很可能用到其相应类型.什么是相应类型?迭代器所指对象的类型便是其中一个.我曾有一个错误的理解,那就是认为相应类型就是迭代器所指对象的类型,其实不然,相应类型是一个大的类别,迭代器 ...

  9. STL之traits编程技法

    traits编程技法利用了“内嵌型别”的编程技巧与编译器的template参数推导功能. 下面主要看看利用traits编程技法实现的迭代器萃取机制. 5种迭代器类型定义: struct input_i ...

随机推荐

  1. MapReduce优化

    Combiner和Partitioner是用来优化MapReduce的,可以提高MapReduce的运行效率.下面我们来具体学习这两个组件 Combiner 我们以WordCount为例,首先通过下面 ...

  2. JAVA中的static修饰的方法不能被重写

    可以重写静态方法,但重写后的静态方法不支持多态. 其实static根本就没有重写之说.static方法引用的时候应该用类名来引用,而不是对象.同时static方法不参与继承,所以在继承体系里面也不存在 ...

  3. Java——(八)Map之LinkedHashMap、TreeMap、EnumMap实现类

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 1.LinkedHashMap实现类 LinkedHashMap需要维护意识的插入顺序,因此性能 ...

  4. 第九章------HAL

    HAL是建立在Linux驱动之上的的程序库,他是一个应用层,它的作用保护内部私有.有一种是位于Android层次的系统运行库层,Linux中只保留与寄存器相互的代码,通过HAL进行数据的传递. 为An ...

  5. springmvc配置文件 spring-servlet

    <?xml version="1.0" encoding="UTF-8"?><!-- Bean头部 --><beans xmlns ...

  6. js--小结⑦---格式转换

  7. 自己动手写控件(模仿mvc htmlhelper的类)

    自定义helper类,要求命名空间在 System.Web.Mvc之下,要求,静态类,静态方法,特殊生成对应html的返回字段, 传递Htmlhleper,返回特定类型 返回值是MvcHtmlStri ...

  8. angularjs kindEditor 中content获得不到值

    angularjs kindEditor 中content获得不到值 需要修改下angular-kindeditor.js angular-kindeditor.js if (KindEditor) ...

  9. 关于ASP.NET控件方面的学习(恢复版)

    前段时间没有把学习中的遇到的问题和解决方法详细总结,今天整理整理.. 鉴于我们这个研究生论文管理系统是小组形式,所以说虽然我只负责数据库,但是其它部分也多少有些工作方面的涉及,最后感谢各位同学和老师的 ...

  10. Ojbect-C2 3、NSArray和NSMutableArray数组的使用

    Adopted Protocols NSCoding encodeWithCoder: initWithCoder: NSCopying copyWithZone: NSMutableCopying ...