磨刀霍霍向STL::distance

平時無所事事,無聊中就把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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章