磨刀霍霍向STL::distance

原创 2004年09月14日 02:39:00

平时无所事事,无聊中就把STL的代码翻出来看,看到部分代码时就突然有了这个想法,其实这只能算个娱乐项目(可能我是极端份子或者可能是变态),如果你现在也无聊,那不妨也来和我变态一把,嘿嘿

这里说的STL其实是SGI STL,下面所有的STL字样都是指的SGI STL,我的STL代码其实就是Dev-C++里面带的。好了废话也差不多说完了,现在正式开始,请把刀拿好,上STL

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

首先来看看 STL中的distance实现(目录就是%include%/c++/bits/stl_iterator_base_funcs.h)

template<typename _InputIterator>

  inline typename iterator_traits<_InputIterator>::difference_type

  __distance(_InputIterator __first, _InputIterator __last, input_iterator_tag)

  {

    // concept requirements

    __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)

 

    typename iterator_traits<_InputIterator>::difference_type __n = 0;

    while (__first != __last) {

      ++__first; ++__n;

    }

    return __n;

  }

 

template<typename _RandomAccessIterator>

  inline typename iterator_traits<_RandomAccessIterator>::difference_type

  __distance(_RandomAccessIterator __first, _RandomAccessIterator __last,

             random_access_iterator_tag)

  {

    // concept requirements

    __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)

    return __last - __first;

  }

 

其中__distance的两个重载版本分别是为了支持输入迭代器(不支持随机访问)和随机访问的迭代器,而我们使用得到的是下面这个distance

template<typename _InputIterator>

  inline typename iterator_traits<_InputIterator>::difference_type

  distance(_InputIterator __first, _InputIterator __last)

  {

    // concept requirements -- taken care of in __distance

    return __distance(__first, __last, __iterator_category(__first));

  }

 

其中distance就使用了__distance这个内部实现,现在来看看我们要修改的地方,其实就在distancereturn语句中,__distance是个重载函数,其中的第三个参数需要调用__iterator_category这个模板函数,然后还要构造一个iterator_category(这只是一个“概念”名字)对象,这样来达到判断iterator_category的作用。

现在我们磨刀的动机就是把__iterator_categoryiterator_category对象的创建这两个调用消除掉,与函数重载相似的东西就是函数模板的偏特化,但是千万别指望这东西,因为C++中没有这玩意。天无绝人之路,我们可以用类模板来实现。代码在下面,比较简单,一看即懂。不过先记得在前面#include <bits/stl_iterator_base_types.h>

template<typename _Iterator, typename _Iterator_Category>

struct __distance{};  //泛化版本

 

//下面就是特化的部分

template<typename _InputIterator>

struct __distance<_InputIterator, input_iterator_tag>

{

    static typename iterator_traits<_InputIterator>::difference_type

    implement(_InputIterator __first, _InputIterator __last)

    {

       // concept requirements

       __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)

       typename iterator_traits<_InputIterator>::difference_type __n = 0;

       while (__first != __last) {

          ++__first; ++__n;

       }

       return __n;       

    }

};

 

template<typename _InputIterator>

struct __distance<_InputIterator, forward_iterator_tag>

{

    static typename iterator_traits<_InputIterator>::difference_type

    implement(_InputIterator __first, _InputIterator __last)

    {

       // concept requirements

       __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)

       typename iterator_traits<_InputIterator>::difference_type __n = 0;

       while (__first != __last) {

          ++__first; ++__n;

       }

       return __n;       

    }

};

 

template<typename _InputIterator>

struct __distance<_InputIterator, bidirectional_iterator_tag>

{

    static typename iterator_traits<_InputIterator>::difference_type

    implement(_InputIterator __first, _InputIterator __last)

    {

       // concept requirements

       __glibcpp_function_requires(_InputIteratorConcept<_InputIterator>)

       typename iterator_traits<_InputIterator>::difference_type __n = 0;

       while (__first != __last) {

          ++__first; ++__n;

       }

       return __n;       

    }

};

 

template<typename _RandomAccessIterator>

struct __distance<_RandomAccessIterator, random_access_iterator_tag>

{

    static typename iterator_traits<_RandomAccessIterator>::difference_type

    implement(_RandomAccessIterator __first, _RandomAccessIterator __last)

    {

       // concept requirements

     __glibcpp_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>)

 

       return __last - __first;   

    }

};

 

上面把内部实现__distance搞定了,现在就来搞定distance

 

template<typename _InputIterator>

  inline typename iterator_traits<_InputIterator>::difference_type

  distance(_InputIterator __first, _InputIterator __last)

  {

    // concept requirements -- taken care of in __distance

return __distance<_InputIterator, iterator_traits<_InputIterator>::iterator_category>::implement(__first, __last);

  }

 

搞定了,你现在来看看你用STL写的程序,其中与distance有关的部分程序是不是效率提高了呀,哈哈哈,你感觉出来我就佩服你了(其实效率差异很小很小)

 

//The End

使用stl中的 advance和 distance 方法来进行iterator的加减

使用stl中的  advance和 distance 方法来进行iterator的加减            以前在遍历vector的时候,经常使用iterator之间的加减来获得元素在容器里面的i...
  • tangaowen
  • tangaowen
  • 2012年04月26日 19:15
  • 11777

VisualStudio中调用SGI版STL的方法

SGISTL是SGI公司发布的一种STL版本,如果看侯捷老师的的话,其中就用的是这个版本,不过大部分人可能用的VisualStudio或者VC编译器,其自带的STL是PJ版本,那么如果希望更好地理解书...
  • Natsume_Kagura
  • Natsume_Kagura
  • 2016年06月05日 22:08
  • 1229

STL示例10(advance及distance使用)

//STL示例 advance及distance #include #include #include //find use #include using namespace std...
  • edcvf3
  • edcvf3
  • 2012年07月03日 19:41
  • 3566

STL(9)之distance函数组源码

1.输入迭代器的版本:
  • wolangjushi
  • wolangjushi
  • 2014年06月30日 14:16
  • 394

C++ STL实例(一)

vector #if 0 /*vector*/ #include #include #include #include using namespace std; int main() { vect...
  • qq_28796345
  • qq_28796345
  • 2016年05月18日 00:17
  • 319

SGI-STL内存池实现及简单使用

这篇博客主要讲一下SGI-STL中的空间配置器的工作流程。我自己实现模仿STL实现了一个空间配置器,并且用两个容器list和vector测试使用了空间配置器。这里只给出模型,如果要看源码,请到http...
  • Chengzi_comm
  • Chengzi_comm
  • 2016年08月15日 12:51
  • 1557

STL学习小结

http://blog.csdn.net/byxdaz/article/details/4633826 STL就是Standard Template Library,标准模板库。这可能是一个历史...
  • jhh_move_on
  • jhh_move_on
  • 2015年05月19日 09:59
  • 3051

C++:distance()

function template std::distance template typename iterator_traits::difference_type dista...
  • jinzhichaoshuiping
  • jinzhichaoshuiping
  • 2017年02月26日 23:34
  • 386

论C++STL源码中关于堆算法的那些事

关于堆,我们肯定熟知的就是它排序的时间复杂度在几个排序算法里面算是比较靠上的O(nlogn)经常会拿来和快速排序和归并排序讨论,而且它还有个优点是它的空间复杂度为O(1), 但是STL中没有给我们提供...
  • swagle
  • swagle
  • 2014年04月22日 23:02
  • 1533

c++STL内存池和空间配置器

c++STL内存池和空间配置器为什么需要空间配置器?内存碎片问题:在软件开发,程序设计中,我们不免因为程序需求,使用很多的小块内存(基本类型以及小内存的自定义类型)。在程序中不断动态申请,释放。这个过...
  • WRNGT
  • WRNGT
  • 2017年07月29日 23:47
  • 432
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:磨刀霍霍向STL::distance
举报原因:
原因补充:

(最多只允许输入30个字)