Iterators

所有容器都有迭代器,string 虽然不是容器,但也能使用迭代器

1
2
vector<int> v = {1, 2, 3};
auto b = v.begin(), e = v.end(); // b and e have the same type

b 指向第一个元素,e 指向最后一个元素的后一个位置

1
2
for (auto it = v.begin(); it != v.end(); ++it)
cout << *it << endl;

迭代器操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
*iter // 解引用
iter->mem // 访问对象成员
(*iter).mem;// 等价于上一个用法
++iter // 引用下一个元素
--iter // 引用上一个元素
iter1 == iter
iter1 != iter2

// 下面的操作对于 vector 和 string 是支持的
iter + n
iter - n
iter += n
iter -= n
iter1 - iter2 // 可以计算得到范围内的元素数量
>, >=, <, <=

Iterator Types

iterator

前面是直接使用 auto 自动判断迭代器类型,可以自己指定迭代器类型

1
2
3
4
5
6
7
8
vector<int> v = {1, 2, 3};
vector<int>::iterator it; // it can read and write vector<int> elements
for (it = v.begin(); it != v.end(); ++it)
cout << *it << endl; // 解引用


string s = "qwt";
string::iterator it2; // it2 can read and write characters in a string

const_iterator

另外还有 const 迭代器类型,和 const 指针一样,只能读取,不能修改

1
2
vector<int>::const_iterator it3; // it3 can read but not write elements 
string::const_iterator it4; // it4 can read but not write characters

begin, end and auto

beginend 返回的类型也取决于容器是否为 const

1
2
3
4
5
vector<int> v;
const vector<int> cv;

auto it1 = v.begin(); // it1 has type vector<int>::iterator
auto it2 = cv.begin(); // it2 has type vector<int>::const_iterator

有的时候默认的返回类型可能不是我们想要的,如果我们想返回 const 迭代器可以使用 cbegin()cend()

1
auto it3 = v.cbegin(); // it3 has type vector<int>::const_iterator

const 容器 不能 使用非 const 迭代器

访问对象成员

1
2
3
4
// 假设 vector 的元素是 string
(*it).empty()
// or
it->empty()

解引用并访问对象的成员时,使用方法和指针是一样的

difference_type

前面提到了迭代器的操作,里面有加减法,实际上两个迭代器之间的偏移量的类型是 defference_type,这是标准库中迭代器的内部类型

1
2
3
4
5
std::vector<int> v = {1, 2, 3, 4, 5};
auto it1 = v.begin();
auto it2 = v.end();
// std::distance 函数来计算两个迭代器之间的元素个数
std::vector<int>::difference_type distance = std::distance(it1, it2);

迭代器加减法就是通过这个类型实现的

1
2
3
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = v.begin();
it += 3; // 使用 difference_type 移动迭代器到第四个元素