STL itertor概念和traits编程技法(一)
来源:互联网 发布:苹果ipad越狱软件 编辑:程序博客网 时间:2024/05/18 00:57
自从C++中引入了template后,以泛型技术为中心的设计得到了长足的进步。STL就是这个阶段杰出的产物。STL的目标就是要把数据和算法分开,分别对其进行设计,之后通过一种名为iterator的东西,把这二者再粘接到一起。设计模式中,关于iterator的描述为:一种能够顺序访问容器中每个元素的方法,使用该方法不能暴露容器内部的表达方式。可以说,类型萃取技术就是为了要解决和iterator有关的问题的,下面,我们就来看看整个故事。
应该说,迭代器就是一种智能指针,因此,它也就拥有了一般指针的所有特点——能够对其进行*和->操作。但是在遍历容器的时候,不可避免的要对遍历的容器内部有所了解,所以,设计一个迭代器也就自然而然的变成了数据结构开发者的一个义务,而这些iterators的表现都是一样的,这种内外的差异,对用户来说,是完全透明的,
一、 为什么要有萃取技术
既然是一种智能指针,iterator也要对一个原生指针进行封装,而问题就源于此,当我们需要这个原生指针所指对象的类型的时候(例如声明变量),怎么办呢?
case1:类型推导
#include<iostream>using namespace std;template<class I,class T>void func_imp(I iter,T t){ T item; item=t; cout<<item<<endl;}template<class I>inline void func(I iter){ func_imp(iter,*iter);}int main(){ int i=9; func(&i); return 0;}
在这个程序里,T是某个指向某个特定对象的指针,在func中需要指针所指向对象类型的变量的时候,利用模板的参数推导机制可以得到T的类型。但是这有一个问题,迭代器类型不只是是所指对象的类别,还包括其他常用型别,而且模板的参数推导也不能推导出返回值类型。
case2:声明内嵌型别
template<class T>struct MyIter{ typedef T value_type; T* ptr; MyItem(T* p=0):ptr(p){} T& operator*() const{ return *ptr;}};template<class I>typename I::value_type func(I iter){ return *iter;}int main(){ MyIter<int> ite(new int(8)); cout<<func(ite)<<endl; return 0;}
typedef T value_type是为所指向的对象的类型添加一个别名,这样在func()函数里面就可以通过typename I::value_type func(I iter)返回value_type对象,typename I::value_type func(I iter)这句不好理解,如果觉得这一段代码难理解的话,不妨改成这样:
template <class T>typename myIter<T>::value_typefunc (myIter<I>){ return *iter;}
不同的只是红色部分;这跟X是一个变量,可以用Y表示;5*X还是一个变量,也可以用Y表示,是一个道理。但是这样的函数不能使用原生指针,比如我们这样使用int *p=new int(6);cout<<func(p)<<endl;编译器就会客气的告诉你出错了Failed to specialize function template 'generic-type-257 __cdecl func(I)。因为编译器不知道I和T的类型,这当然不行。
case3:类型萃取
/*1.当T为内嵌型别时,通过类型推导获取型别 *2.当T为原生指针的或者pointer-to-const的时候,通过iterator_traits偏特化获取型别*/#include <iostream>using namespace std;template <class I>struct myiterator_traits{ typedef typename I::value_type value_type;};//特化版本1,T为原生指针template<class T> struct myiterator_traits<T*> { typedef T value_type;};//特化版本2,T为const-to-pointertemplate<class T> struct myiterator_traits<const T*> { typedef T value_type;};//自定义类型MyItertemplate<class T>struct MyIter{ typedef T value_type; T* ptr; MyIter(T* p=0):ptr(p){} T& operator*() const{ return *ptr;}};template<class I>typename myiterator_traits<I>::value_typefunc(I iter){ return *iter;}int main(){ MyIter<char> ite(new char('f'));//当T为自定义类型 cout<<func(ite)<<endl; int *p=new int(6); //当T为原生指针时 cout<<func(p)<<endl; const int *t=new int(9); //当T为pointer-to-const时 cout<<func(t)<<endl; return 0;}
这样就可以了。不仅可以接受各种类或基本类型作为迭代对象,而且接受原生指针作为迭代器。
- STL itertor概念和traits编程技法(一)
- STL itertor概念和traits编程技法(二)
- STL中迭代器概念与traits编程技法
- STL 迭代器概念及traits编程技法
- 《STL源码剖析》——迭代器(iterators)概念与traits编程技法(一)
- STL三:Traits编程技法一
- STL-迭代器和traits编程技法
- STL学习笔记(traits编程技法)
- Traits编程技法一
- STL源码剖析-迭代器概念与traits编程技法
- STL之traits编程技法
- STL之traits编程技法
- STL中的traits编程技法
- STL中traits编程技法
- 《STL源码剖析》——迭代器(iterators)概念与traits编程技法(二)
- C++ traits编程技法(一)
- STL笔记(6)——Traits编程技法(一)
- 3 迭代器与概念和traits编程技法
- cocos2d-x创建精灵动画
- 冒泡排序
- Centos 使用RepoForge
- 智能指针
- 快速排序C++实现
- STL itertor概念和traits编程技法(一)
- 侯捷观点
- apue源码make:/usr/include/bits/timex.h:31:7: 错误:expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ be的解决方法
- quantum命令行创建和删除网络
- Linux编译安装boost
- codeblocks环境配置
- Ubuntu下的系统备份
- POJ 3207 Ikki's Story IV - Panda's Trick 2-SAT
- VS2010编译boost