在使用vector、string、deque等容器时,遍历容器中的元素,查找容器中的元素以及各种对容器中元素的操作,都离不开迭代器的使用。
我在敲代码的时候经常会报错的一点就是迭代器之间的运算会出错,运算符“+”报错是没有与这些操作数匹配的“+”运算符。反而迭代器的减法不会报错。
比如

auto s = v.end() - v.begin();	//不报错
auto m = v.end() + v.begin();	//“+”报错:没有与这些操作数匹配的“+”运算符

这个是为什么呢?

迭代器之间减法运算

迭代器之间的减法是被允许的,两个迭代器相减返回是它们之间的距离,这个距离是一个符号类整型(signed),意味着两个迭代器之间相减可能是正数、零或者负数。其实string和vector中已经是定义了两个迭代器相减是返回difference_type的。difference_type也可以理解为带符号整形数(signed)。

因此如下的代码都是没有错误的,并且返回的都是容器内元素的个数。

auto dist1 = v.end() - v.begin();
signed dist2 = v.end() - v.begin();
vector<int>::difference_type dist3 = v.end() - v.begin();

迭代器之间加法运算

迭代器之间的加法运算是不被允许的,其实迭代器就可以相当于指针,那么学习指针的时候我们只学过指针相减运算。

int a = 1;
int b = 2;
int* p1 = &a;
int* p2 = &b;
auto n = p1 - p2;

此时的n的值为3,表示的是p1和p2在内存中的地址相差了几个指针类型的字节倍数。

但是指针的相加是不被允许的,想象一下地址之间的相加有何意义,因此迭代器之间的加法是不被允许的。

迭代器与整数相加减

迭代器++和–很好理解。迭代器与整数相加减返回的还是一个迭代器,跟指针加上一个整数是类似的,指向的位置发生改变。下面的代码是合法的:

auto it = v.begin()+ 2;	//迭代器it的位置为第三个元素
auto it1 = v.end() - 2;	//迭代器it1的位置为倒数第二个元素

如何获得一个迭代器在容器中的位置呢?

运用distance函数方法

int val = distance(v.begin(), pos);

返回的val就是迭代器pos在vector容器v中的第几个位置,val是一个整型类型。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐