迭代器类似于指针类型,提供了对对象的间接访问。迭代器的对象是容器中的元素或string中的字符。使用迭代器可以访问某个元素,也能从一个元素移动到另外一个元素。有效的迭代器或者指向某个元素,或者指向容器中尾元素的下一位置,其他情况都属于无效。
3.4.1 使用迭代器
和指针不同的是,获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员。比如,这些类型都拥有名为begin和end的成员。begin成员负责返回指向第一个元素(或第一个字符)的迭代器,end成员负责返回指向容器(或string对象)“尾元素的下一位置”的迭代器。这样的迭代器没什么实际含义,只是用于标记,表示已处理完容器中的所有元素。end成员返回的迭代器被称为尾后迭代器或尾迭代器。特殊情况下如果容器为空,则begin和end返回同一个迭代器,都是尾后迭代器。
迭代器运算符
- *iter 返回迭代器iter所指元素的引用
- iter->mem 解引用iter并获取该元素名为mem的成员,等价于(*iter).mem
- ++iter 令iter指示容器中的下一个元素
- --iter 令iter指示容器中的上一个元素
- iter1 == iter2 两个迭代器相等的条件:指向同一个元素或都是同一个容器的尾迭代器。
因为end返回的迭代器并不实际指示某个元素,所以不能对其进行递增与解引用操作。
string s("some string");if (s.begin() != s.end()) { auto it = s.begin(); *it = toupper(*it);}
for (auto it = begin(); it != s.end() && !isspace(*it); ++it) *it = toupper(*it);
泛型编程:在容器中使用!=和迭代器取代<和下标运算符
迭代器类型
iterator 和 const_iterator。begin和end返回类型由对象是否是常量决定。有时这种默认行为并非我们所要。如果对象只需读操作不需写操作最好使用常量类型。
auto it3 = v.cbegin(); //it3的类型为vector<int>::const_iterator
cbegin,cend不论对象是否常量,返回类型都是const_iterator
凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素
3.4.2 迭代器运算
iter1-iter2 两个迭代器相减的结果是他们之间的距离。两个迭代器必须指向同一个容器中的元素。
auto beg = text.begin(),end = text.end();auto mid = text.begin() + (end - beg)/2;while(mid != end && *mid != sought) { if (sought < *mid) end = mid; else beg = mid + 1; mid = beg + (end - beg)/2;}