标签:
在stl的算法中,我们的希望往往是根据不同的迭代器类型进行不同的更有效率的操作:
1 template<typename IterT, typename DistT> 2 void advance(IterT iter, DistT dis) 3 { 4 if(iter is a random access iterator) 5 iter += dis; 6 else{ 7 if(dis >= 0){ 8 while(dis--) 9 iter++; 10 }else{ 11 while(dis++) 12 iter--; 13 } 14 } 15 };
这种可以识别Iterator类别的技术叫做iterator_traits,首先起要求每一个用户自定义的迭代器类型都应该有个typedef,类似下面这样:
1 template<...> 2 class list{ 3 public: 4 class iterator{ 5 typedef typename bidirectional_iterator_tag iterator_category; 6 ... 7 }; 8 };
这样iterator_traits就可以通过萃取技术将迭代器的类型给萃取出来:
1 template<typename IterT> 2 struct iterator_traits 3 { 4 typedef typename IterT::iterator_category iterator_category; 5 ... 6 };
1 tempalte<typename IterT> 2 struct iterator_traits<IterT *> 3 { 4 typedef random_access_iterator_tag iterator_category; 5 ... 6 };
有了iterator_traits技术以后,实现有效率的迭代就是可能的了。但是实际上不是通过 if Iterator is a random_access_iterator这种形式来实现的,而是通过函数的重载来实现的:
1 template<typename IterT, typename DistT> 2 doAdvance(IterT iter, DistT d, std::random_access_iterator_tag)//这里的tag往往先通过iterator_traits进行萃取而得到的; 3 { 4 iter += d; 5 } 6 template<typename IterT, typename DistT> 7 doAdvance(IterT iter, DistT d, std::bidirectional_iterator_tag) 8 { 9 if(dis >= 0){ 10 while(dis--) 11 iter++; 12 }else 13 while(dis++) 14 iter--; 15 } 16 tempalte<typename IterT, typename DistT> 17 doAdvance(IterT iter, DistT d, std::input_iterator_tag) //注意这里的迭代器版本 18 { 19 if(d < 0) 20 throw std::out_of_range("Negetive distance!"); 21 else{ 22 while(d--) ++iter; 23 } 24 }
1 template<typename IterT, typename DistT> 2 doAdvance(IterT iter, DistT d) 3 { 4 doAdvance(iter, d, 5 typename std::iterator_traits<IterT>::iterator_category()); //注意这里使用到了typename 6 }
标签:
原文地址:http://www.cnblogs.com/-wang-cheng/p/4889832.html