首页 > 代码库 > 3.4 迭代器

3.4 迭代器

迭代器类似于指针类型,提供了对对象的间接访问。迭代器的对象是容器中的元素或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;
}

 

3.4 迭代器