转自: https://blog.csdn.net/GUI1259802368/article/details/72737331?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control

在算法中运用迭代器时,很可能会用到其相应型别,什么是相应型别?迭代器所指之物的型别便是其中之一。C++ 有函数模版推导机制,例如:

template<class I ,class T>
void  func_imp1(I iter, T t)
{
       T tmp;      // 这里解决了问题,T就是迭代器所指之物的型别,本例为int
};
template <class I>
inline  void func(I  iter)
{
       func_imp1(iter ,*iter);        // func 的工作全部移往 func_imp1
}
int main()
{
      int i;
      func(&i);
}

迭代器所指对象的型别。成为该迭代器的 value type。上述的参数型别推导虽然可用于value_type,但是当value type 必须用于函数的传回值,就束手无策了,毕竟函数的 “template 参数推导机制” 推而导之的只是参数,无法推导函数的返回值型别。

其他方法如声明内嵌型别似乎是个好主意,例如:

template<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 I:: value_type
func(I ite)
{  return *ite;  }
//...
MyIter<int>ite(new  int(8));
cout<<func(ite);

注意:并不是所有的迭代器都是 class type。原生指针就不是!如果不是 class type,就无法为它定义内嵌型别。但是STL绝对必须接受原生指针作为一种迭代器,因此需要一种方法将上述的一般化概念针对特定情况做特殊化处理。

偏特化就可以做到,如下面一个class template:

template<typename T>
class  C {  ...  };          //这个泛化版本允许T为任何型别
很容易接受它有一个形式如下的 partial specialization:
template<typename T>
class C<T*>{  ...  };     //这个特化版本仅适用于“T为原生指针”的情况
                                   // “T为原生指针” 便是 “T为任何型别” 的一个更进一步的条件限制

下面这个 class template 专门用来 “萃取”迭代器的特性,而 value type正是迭代器的特性之一:

template<class I>
struct  iterator_traits{
    typedef  typename I::value_type     value_type;
};

这个所谓的 traits,其意义是,如果 I 定义有自己的 value_type,那么通过这个 traits 的作用,萃取出来的 value_type 就是 I:: value_type.换句换说,如果I定义有自己的 value type,先前那个 func() 可以改写成这样:

template<class I>
typename iterator_traits<I>::value_type
func(I  ite)
{ return  *ite; }

但是除了多一层间接性,又带来什么好处呢?好处是 traits 可以拥有特化版本。现在,我们令 iterator_traits 拥有一个 partial specializations 如下:

template<class  T>
struct  iterator_traits<T*>{           //偏特化版本------迭代器是个原生指针
    typedef   T  value_type;
};

最常用到的迭代器的相应型别有五种:value type,difference type,pointer,reference,iterator,iterator catagoly。如果你希望你所开发的容器能与STL水乳交融,一定要为你的容器的迭代器定义这五种相应型别。特性萃取机 traits 会很忠实的提取出来:

template<class  I>
struct  iterator_traits{
   typedef  typename  I:: iterator_category     iterator_category;
   typedef  typename  I:: value_type               value_type;
   typedef  typename  I:: difference_type       difference_type;
   typedef  typename  I:: pointer                     pointer;
   typedef  typename  I:: reference                 reference;
}; 

标签: C++

添加新评论