平时无所事事,无聊中就把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这个内部实现,现在来看看我们要修改的地方,其实就在distance的return语句中,__distance是个重载函数,其中的第三个参数需要调用__iterator_category这个模板函数,然后还要构造一个iterator_category(这只是一个“概念”名字)对象,这样来达到判断iterator_category的作用。
现在我们磨刀的动机就是把__iterator_category和iterator_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