3.4 迭代器
3.4 迭代器(iterator)
迭代器支持一套操作,这套操作使得我们能访问容器的元素或者从某个元素移动到另外一个元素。
迭代器提供了对对象的间接访问。迭代器有有效和无效之分,有效的迭代或者指向某个元素,或者指向容器中尾元素的下一位置,其他情况都属于无效。
3.4.1 使用迭代器
获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员。begin
成员负责返回指向第一个元素的迭代器,end
成员负责返回指向容器尾元素的下一个位置的迭代器。
// 由编译器决定 b 和 e 的类型
// b 表示 v 的第一个元素,e 表示 v 尾元素的下一位置
auto b = v.begin(), e = v.end(); // b 和 e 的类型相同
迭代器运算符
执行解引用的迭代器必须合法并确实指着某个元素,不能是非法迭代器或者尾后迭代器。
将迭代器从一个元素移动到另一个元素
使用递增++
运算符来从一个元素移动到下一个元素,迭代器的递增则是将迭代器”向前移动一个位置“。
for(auto iter = s.begin(); iter != s.end() && !isspace(*iter); ++iter)
*iter = toupper(*iter);
迭代器类型
拥有迭代器的标准库类型使用iterator
和const_iterator
来表示迭代器的类型。
const_iterator
能读取但不能修改它所指的元素值。iterator
的对象可读可写。
begin 和 end 运算符
vector<int> v;
auto it1 = v.begin(); // 返回类型是 iterator
auto it2 = v.end(); // 返回类型是 iterator
auto it3 = v.cbegin(); // 返回类型是 const_iterator
auto it4 = v.cend(); // 返回类型是 const_iterator
结合解引用和成员访问操作
箭头运算符->
结合了解引用和成员访问两个操作,it->mem
和(*it).mem
等价。
某些对 vector 对象的操作会使迭代器失效
使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。
3.4.2 迭代器运算
迭代器的算术运算
令迭代器和一个整数值相加或相减,其返回值是向前或向后移动了若干个位置的迭代器。执行这样的操作时,结果迭代器或者指向原对象内的一个元素,或者指向元对象尾元素的下一位置。
使用迭代器运算
使用迭代器进行二分搜索
auto beg = text.cbegin(), end = text.cend();
auto mid - text.cbegin() + (end - beg) / 2;
while(mid != end && *mid != sought)
if(sought < *mid)
end = mid;
else
beg = mid + 1;
mid = beg + (end - beg) / 2;