C/C++ iterator

  1. std::iterator
template< class Category,class T,class Distance = std::ptrdiff_t,class Pointer = T*,class Reference = T& > 
struct iterator;

std::iterator 的模板参数:

  • Category: 类型为 iterator_category,表示迭代器的种类,共有5类:在这里插入图片描述

  • T :类型为 value_type, 可以通过解除引用迭代器获得的值的类型。 对于输出迭代器,此类型应为 void。

  • Distance: 类型为 difference_type, 一种可用于标识迭代器之间距离的类型。即两个迭代器相减(若支持的话)的结果类型。

  • Pointer: 类型为 pointer,定义指向迭代类型的指针(T)。即指向 T 类型的指针。

  • Reference: 类型为 reference,定义迭代类型的引用(T)。即 T 的引用类型。

如自定义一个继承自 std::iterator 的迭代器:

#include <algorithm>
#include <iterator>
using namespace std;

template<long FROM, long TO>
class Range
{
public:
	class Longiterator : public std::iterator<std::input_iterator_tag,  //@ iterator_category
		long, //@ value_type
		long, //@ difference_type
		const long*, //@ pointer
		long> //@ reference
	{
		long num_ = FROM;
	public:
		explicit Longiterator(long num = 0) : num_(num) {}
		Longiterator& operator++() { num_ = TO > FROM ? num_ + 1 : num_ - 1; return *this; }
		Longiterator operator++(int) { Longiterator retval = *this; ++(*this); return retval; }
		bool operator==(Longiterator other)const { return num_ == other.num_; }
		bool operator!=(Longiterator other)const { return !(*this == other); }
		reference operator*()const { return num_; }
	};

	Longiterator begin() { return Longiterator(FROM); }
	Longiterator end() { return Longiterator(TO > FROM ? TO + 1 : TO - 1); }
};

int main()
{
	auto range = Range<2, 10>();
	auto iter = std::find(range.begin(),range.end(),8);
	cout << *iter << endl;

	//@ range_based for 
	for (const auto& elem : range)
		cout << elem << " ";
	cout << endl;

	return 0;
}

8
2 3 4 5 6 7 8 9 10

  1. std::iterator_traits
    STL 中的算法与容器之间是通过迭代器架起的桥梁,算法需要知道迭代器的信息,以便采用最优算法。但是算法如何知道迭代器的详细信息呢,此时就需要一个中间层:iterator_traits,它也是一个模板类,将 iteratoe进行了包装,并使用模板局部特化技术:
//使用iterator提供的信息
template<typename Iterator>
struct iterator_traits
{
  typedef typename Iterator::iterator_category iterator_category;
  typedef typename Iterator::value_type        value_typep;
  typedef typename Iterator::difference_type   difference_type;
  typedef typename Iterator::pointer           pointer;
  typedef typename Iterator::reference         reference;
};

//@ 局部特化,c++内置指针。
template<typename T>
struct iterator_traits<T *>
{
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef T*                         pointer;
  typedef T&                         reference;
};

//@ 局部特化,const c++内置指针。
template<typename T>
struct iterator_traits<const T *>
{
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type; //@ 注意这里不是const T;如果是const T,算法拿到这个类型,用这个类型定义变量后,却无法改变其值,那就没有作用了,所以是T。
  typedef ptrdiff_t                  difference_type;
  typedef const T*                   pointer;
  typedef const T&                   reference;
};

例如:list类的size方法。

size_type size() const {
  size_type result = 0;
  distance(begin(), end(), result);
  return result;
  //return distance(begin(), end());    
}

struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};

template <class InputIterator, class Distance>
inline void __distance(InputIterator first, InputIterator last, Distance& n, 
                       input_iterator_tag)
{
  while (first != last) { ++first; ++n; }
}

template <class RandomAccessIterator, class Distance>
inline void __distance(RandomAccessIterator first, RandomAccessIterator last, 
                       Distance& n, random_access_iterator_tag)
{
  n += last - first;
}

template <class Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&) {
  typedef typename iterator_traits<Iterator>::iterator_category category;      //@ 1
  return category();
}

template <class InputIterator, class Distance>
inline void distance(InputIterator first, InputIterator last, Distance& n)
{
  __distance(first, last, n, iterator_category(first));
}

代码1处,算法向 iterator_traits 要 iterator_category 的信息,如果 iterator 能提供,就使用 iterator 里的 iterator_category,如果 iterator 不能提供,就使用 iterator_traits 里的 iterator_category。得到iterator_category 后,就可以在编译阶段确定调用哪一个 __distance 方法了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值