前言
</br>
正如上一节所说,insert与erase只支持iterator或能隐式转为iterator的迭代器。如果我们只有一个const_iterator,那怎么办?有人会试图去使用类型转换:1
2
3
4
5typedef deque<int> IntDeque;
typedef IntDeque::iterator Iter;
typedef IntDeque::const_iterator ConstIter;
ConstIter ci; // ci是const_iterator
Iter i(const_cast<Iter>(ci)); //error
不能类型转换原因是很简单的,const_iterator与iterator是完全不同的类,就像string与vector<int>没有任何关联一样。
解决思路
1 | typedef deque<int> IntDeque; |
advance与distance都在头文件<iterator>
中。
distance返回两个指向同一个容器的iterator之间的距离;advance则用于将一个iterator移动指定的距离。
如果i和ci指向同一个容器,那么表达式advance(i, distance(i,ci))会将i移动到与ci相同的位置上。
思路很美好,但实际上这段程序不能编译通过。
解决方案
无法编译的原因
distance的定义式如下:1
2
3template<typename InputIterator>
typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last);
我们可以清楚地看到distance要求两个参数必须一致,最起码能完成隐式转换,而实际上const_iterator无法转换。
显式指定函数模板参数
通过显式地指明distance调用的模板参数类型,那么编译器则不再从参数推断函数模板参数:1
advance(i, distance<ConstIter>(i, ci));
效率
对于随机迭代器(vector,string,deque)消耗常数时间,双向迭代器(所有其他容器)需要线性的时间。