迭代器类似于指针类型,可以对对象的间接访问。
迭代器有有效和无效之分:有效的迭代器要么指向某一个元素,要么指向容器中尾元素的下一个位置,其他情况都属于无效的。
有迭代器的类型同时拥有返回迭代器的成员。
最常见的迭代器是:begin()和end(),cbegin和cend(),rbegin()和rend()....
由上面可以知道就它们两个就有多个版本,带r的版本返回反向迭代器,带c的版本返回const迭代器。(当我们不需要写访问的时候就应该使用带c的迭代器)
迭代器的类型:迭代器拥有标准库类型使用iterator和const_iterator(和常量指针差不多)来表示迭代器的类型。
其中带c的版本是C++11新引入的,用以支持auto与begin和end函数结合使用。
list <string>::iterator it1 = a.begin();
list <string>::const_iterator it2 = a.begin();
//是itertor还是const_iterator依赖于a的类型
auto it3 = a.begin();//仅当a是const时,it3是 const_iterator
auto it4 = a.cbegin(); //it4是const_iterator
迭代器begin成员负责返回指向第一个元素的;而end(尾后迭代器)成员负责返回指向容器尾元素的下一个位置。
如果容器为空,则begin和end返回的是同一个迭代器。
标准容器库迭代器的运算:
*iter | 返回迭代器iter所指元素的引用 |
iter->mem | 解引用iter并获取该元素的名为mem的成员,等价于(*iter).mem 。这里加了个括号是运算等级问题 |
++iter | 令iter指示容器中的下一个元素 |
--iter | 令iter指示容器中的上一个元素 |
iter1 == iter2 | 它们是否相等,如果两个迭代器指示的是同一个元素或者它们是同一个容器的尾后迭代器,则相等,反之不相等; |
iter1 != iter2 |
注意:因为end()返回的迭代器并不是实际指示某个元素,所以不能对它进行递增或解引用的操作。
这被称为左闭合区间: 【begin,end)
解引用和成员访问操作:
(*it).empty(); //正确
*it.empty(); //错误
上面代码中圆括号是必不可少的,因为运算等级优先级的关系,我们原意是先it解引用,用解引用的结果执行点运算符;如果不加括号,点运算符将会由it来执行,而不是It解引用的结果。它们执行 的顺序错了。
注意:但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。
迭代器的算术运算:
vector<int > v1{1,2,3,4,5,6};
vector<int >::difference_type i;
i=v1.end()-v1.begin();//得到两个迭代器之间的距离(前提是两个迭代器必须指示同一个容器)
cout<<i<<endl;
//上面的距离是指右侧的迭代器向前移动多少位置就能追上左侧的迭代器。
迭代器和一个整数相加减,返回值是向前或向后移动了若干个位置的迭代器。
迭代器和迭代器之间进行运算,返回的结果类型是 difference_type,在实际使用的时候我们可以直接使用auto自动推导。由于表示距离,所以它可正可负,它是一个带符号整形数。