正反向迭代器的应用
正向迭代器可以用于正向遍历,反向迭代器则便于反向遍历。
但若要进行插入与删除操作,则只有正向迭代器可以做到。
但有时,我们需要反向查找到一个位置并进行插入与删除操作。
此时需要进行正反向迭代器的转换。
正反向迭代器的转换
reverse_iterator与iterator都继承自_Iterator_base,它们是可以相互转换的。
- 调用reverse_iterator的base()方法可以获取对应的iterator。
- 可以用iterator构造一个对应的reverse_iterator。
list<int>::iterator it = rit.base();
list<int>::reverse_iterator rit(it);
正反向迭代器的关系
STL源码处注释如下:
/**
* Bidirectional and random access iterators have corresponding reverse
* %iterator adaptors that iterate through the data structure in the
* opposite direction. They have the same signatures as the corresponding
* iterators. The fundamental relation between a reverse %iterator and its
* corresponding %iterator @c i is established by the identity:
* @code
* &*(reverse_iterator(i)) == &*(i - 1)
* @endcode
*
* <em>This mapping is dictated by the fact that while there is always a
* pointer past the end of an array, there might not be a valid pointer
* before the beginning of an array.</em> [24.4.1]/1,2
*
* Reverse iterators can be tricky and surprising at first. Their
* semantics make sense, however, and the trickiness is a side effect of
* the requirement that the iterators must be safe.
*/
即反向迭代器rit解引用与正向迭代器it的前一个位置解引用指向同一个地址。
对于反向迭代器,很重要的一点是需要弄清楚其逻辑位置和实际位置二者的区别。反向迭代器所指位置(实际位置)和所代表的的数值(逻辑位置)是不同的,逻辑位置总是在实际位置前。见下图:
因此转换时实际位置不变,但逻辑位置发生了变化。其中,逻辑位置可以通过解引用来确定,实际位置可以通过base()方法来确定。
由于所有容器都要遵循左开右闭的原则,反向迭代器的设计者运用了一个小技巧:他们实际上倒置了“半开原则”。