磨刀霍霍向STL::distance

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

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

 

首先来看看 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

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

  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

你可能感兴趣的:(C++实践)