现在的位置: 首页 > 综合 > 正文

STL源码剖析_读书笔记:第三章 迭代器概念与traits编程技法

2018年05月18日 ⁄ 综合 ⁄ 共 4422字 ⁄ 字号 评论关闭

迭代器模式:提供能够按序访问容器中元素且屏蔽容器差异性的方法

迭代器本质:是行为类似指针的对象,对operator*
operator->重载。

迭代器的特点:每个容器有自己的迭代器

迭代器型别:迭代器所指对象型别value_type(typedeif()获得型别名称)

 

 

STL中心思想:将容器和算法分开,用迭代器作为桥梁进行两者的嫁接

偏特化意义:若类模板有多个模板参数,可对其中某参数进行特化

 

 

Traits作用:

如果模板参数有自己的value_type

原声指针无法定义型别,需通过类模板的偏特化得到型别,而迭代器能定义自己的型别

 

常用迭代器型别:

Value_type:迭代器所指对象的型别

Difference_type:两个迭代器之间距离,可表示容器的容量

Pointer:用来指向迭代器所指之物

Reference: 解引用时获取左值,因为右值不允许赋值。传左值用引用。

Iterator_category

 

迭代器的类型:允许改变所指对象内容为mutable_iterator,不允许改变所指对象内容为consant iterators

迭代器的种类:

Input Iterator:只读

Output Iterator:只写

Forward Iterator:读写

Bidirectional Iterator:双向移动

Random Access Iterator:所有指针算术能力

 

5种迭代器类型:

Struct input_iterator_tag{};

Struct output_iterator_tag{};

Struct forward_iterator_tag{};

Struct bidirectional_iterator_tag : public input_iterator_tag{};

Struct random_access_iterator_tag : public bidirectional_iteratir_tag{};

 

迭代器类型应该属于最强化(最特殊的那个)的那个

 

Traits编程技法:利用内嵌型别+模板参数推导

SGI STL__type_traits:”__”表示是SGI特有的

 

Iterator_traits:获取迭代器的特性

__type_traits:获取型别(type)的特性:型别是否含有有意义的默认构造,拷贝构造函数等

 

下面的程序是关于traits:

#include<iostream>
#include<string>
#include<vector>
#include<iterator>

using namespace std;

//真正的实现函数
template<class I,class T>
void fooImpl(I iter,T t)
{
 T tmp;//T是迭代器所指植物的型别
 cout<<"这是实现函数"<<endl;
}

//对外接口
template<class T>
inline void f00(T iter)
{
 cout<<"这是接口"<<endl;
 fooImpl(iter,*iter);
}

//将value_type用于函数的返回值
template<class T>
class MaIter
{
 
public:
 MaIter(T* p=0):ptr(p){}
 T& operator*() const {return *ptr;}

public:
 typedef T value_type;//内嵌型别
 T *ptr;
};

template<class T>
typename T::value_type func(T iter)//func返回类型必须加上typename,因为T是模板参数,告知编译器MaIter<T>::value_type是型别
{
 return *iter;
}

template<class T>
class iterator_traits_ma
{
public:
 typedef typename T::value_type value_type;
};

//traits可有有特化版本
template<class T>
typename iterator_traits_ma<T>::value_type foo(T iter)
{
 return *iter;
}

//当迭代器是指向的是常对象时,提取出来的型别应为T
//template<class T>
//struct iterator_traits_ma1<const T*>
//{
//public:
// typedef T value_type;
//};

//迭代器的常用型别
template<class T>
struct iterator_traits_chao
{
 typedef typename T::iterator_category iterator_category;
 typedef typename T::value_type value_type;
 typedef typename T::difference_type difference_type;
 typedef typename T::pointer pointer;
 typedef typename T::reference reference;
};

//针对原生指针的偏特化版本
template<class T>
struct iterator_traits_chao<T*>
{
 typedef ptrdiff_t difference_type;
 typedef T* pointer;
 typedef T& reference;
 typedef random_access_iterator_tag iterator_category;
 typedef T value_type;

};

//针对原生的pointer-to-const的偏特化版本
template<class T>
struct iterator_traits_chao<const T*>
{
 typedef ptrdiff_t difference_type;
 typedef T value_type;
 typedef const T* pointer;
 typedef const T& reference;
 typedef random_access_iterator_tag iterator_category;
};

//作用:决定迭代器的类型
template<typename Iterator>
inline typename iterator_traits_chao<Iterator>::iterator_category
 iterator_category(const Iterator&)
{
 typedef typename iterator_traits_chao<Iterator>::iterator_category category;
 return category();
}

//需要迭代器的difference_type的写法
//typename iterator_traits_chao<T>::difference_type;

struct input_iterator_tag_m{};
struct output_iterator_tag_m{};
struct forward_iterator_tag_m{};
struct bidirectional_iterator_tag_m : public input_iterator_tag_m{};
struct random_access_iterator_tag_m : public bidirectional_iterator_tag_m{};

template<class InputIterator,class Distance>
inline void _advance(InputIterator& i,Distance n,input_iterator_tag_m)
{
 //逐一前进
 while(n--)
 {
  ++i;
 }
}

template<class ForwardIterator,class Distance>
inline void _advance(ForwardIterator& i,Distance n,forward_iterator_tag_m)
{
 _advance(i,n,input_iterator_tag);
}

template<class BidrectionalIterator,class Distance>
inline void _advance(BidrectionalIterator& i,Distance n,bidirectional_iterator_tag_m)
{
 //双向逐一前进
 if(n>=0)
 {
  while(n--)
  {
   ++i;
  }
 }
 else
 {
  while(n++)
  {
   --i;
  }
 }
}

template<class RandomAccessIterator,class Distance>
inline void _advance(RandomAccessIterator& i,Distance n,random_access_iterator_tag_m)
//random_access_iterator_tag_m只是用来激活重载机制,函数中不使用该参数
{
 //双向,跳跃前进
 i += n;
}

template<class InputIterator,class Distance>
inline void advance_m(InputIterator& i,Distance n)
{
 _advance(i,n,iterator_traits_chao<InputIterator>::iterator_category());//用traits机制从迭代器中推导出类型
 //iterator_traits_chao<InputIterator>::iterator_category()产生一个暂时对象,型别为5个迭代器类型之一
}

//每个新设计的迭代器都继承它
template<class Category,class T,class Distance = ptrdiff_t,class Pointer = T*,class Reference = T&>
struct iterator
{
 typedef Category iterator_category;
 typedef T value_type;
 typedef Distance difference_type;
 typedef Pointer pointer;
 typedef Reference reference;
};

 

int main(int argc,char *argv[])
{
 MaIter<int> iter(new int(1));
 cout<<func(iter);
 cout<<"原生指针的迭代器不是class type"<<endl;
 
 getchar();
 return 0;
}

 

抱歉!评论已关闭.