平時無所事事,無聊中就把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這個內部實現,現在來看看我們要修改的地方,其實就在distance的return語句中,__distance是個重載函數,其中的第三個參數需要調用__iterator_category這個模板函數,然後還要構造一個iterator_category(這只是一個“概念”名字)對象,這樣來達到判斷iterator_category的作用。
現在我們磨刀的動機就是把__iterator_category和iterator_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