忘了从哪里抄的
1 什么是迭代器
迭代器(Iterator)是按照一定的顺序对一个个容器中的元素从前往遍历的一种机制,而又不需要暴漏该对象的内部细节。
2. C++迭代器种类说明
C++中的容器一般会提供四个迭代器:
iterator
正向迭代器,从前往后遍历,可修改元素的值const_iterator
正向常量迭代,但不能修改元素的值,因为指向的是const的引用reverse_iterator
反向迭代,从后往前遍历,可修改元素的值const_reverse_iterator
反向常量迭代,但不能修改元素的值,因为指向的是const的引用。
迭代器类型 | 开始位置标志 | 末尾位置标志 | 说明 |
---|---|---|---|
iterator | begin() | end() | 正向迭代 |
const_iterator | cbegin() | cend() | 正向常量迭代 |
reverse_iterator | rbegin() | rend() | 反向迭代 |
const_reverse_iterator | crbegin() | crend() | 反向常量迭代 |
3. C++ 迭代器功能说明
章节2中介绍了迭代器的种类说明,比如vector
提供了四种迭代器,其中的iterator
为正向迭代器,但不仅仅是正向按下标一个个迭代这么简单,它还可以提供随机访问。
常用的迭代器按功能强弱分为输入、输出、正向、双向、随机访问五种,这里只介绍常用的三种。
- 正向迭代器。假设 p 是一个正向迭代器,则 p
支持以下操作:++p,p++,*p。此外,两个正向迭代器可以互相赋值,还可以用==和!=运算符进行比较。
- 双向迭代器。双向迭代器具有正向迭代器的全部功能。除此之外,若 p 是一个双向迭代器,则–p和p–都是有定义的。–p使得 p
朝和++p相反的方向移动。
- 随机访问迭代器。随机访问迭代器具有双向迭代器的全部功能。若 p 是一个随机访问迭代器,i 是一个整型变量或常量,则 p
还支持以下操作: p+=i:使得 p 往后移动 i 个元素。 p-=i:使得 p 往前移动 i 个元素。 p+i:返回 p 后面第 i
个元素的迭代器。 p-i:返回 p 前面第 i 个元素的迭代器。 p[i]:返回 p 后面第 i 个元素的引用。
表1:不同容器的迭代器的功能
容器 | 迭代器功能 |
---|---|
vector | 随机访问 |
deque | 随机访问 |
list | 双向 |
set / multiset | 双向 |
map / multimap | 双向 |
stack | 不支持迭代器 |
queue | 不支持迭代器 |
priority_queue | 不支持迭代器 |
4. 接口
1. advance
使容器前进n
个元素,
void IteratorSuite::advance()
{
std::list<int> a = { 0, 1, 2, 3, 4, 5 };
auto it = a.begin();
std::advance(it, 3);
TEST_ASSERT_EQUALS(3, *it);
}
5 自定义类型迭代器
template <typename T>
class arrIterator
{
public:
arrIterator() {};
arrIterator(T* start) : ptr(start) {};
arrIterator& operator++() {
++ptr;
return *this;
}
T& operator*() {
return *ptr;
}
T* operator->() {
return ptr;
}
bool operator!=(const arrIterator& other) {
return ptr != other.ptr;
}
bool operator==(const arrIterator& other) {
return ptr == other.ptr;
}
private:
T* ptr;
};
/*********以下操作似乎是不允许的**********
* 添加元素会使得end()指向不对
* 中间插入元素使得end也不对
*************************************/
class MyClass
{
public:
MyClass() {};
~MyClass() {};
arrIterator<int> begin() {
return arrIterator<int>(&member[0]);
}
arrIterator<int> end() {
return arrIterator<int>(&member[0] + count);
}
void push_back(int value) {
if (count < 10) {
member[count] = value;
count++;
}
}
private:
int member[10];
int count = 0;
};
int main()
{
MyClass myClass;
for (int i=0; i<5; ++i)
{
myClass.push_back(i);
}
for(arrIterator<int> it = myClass.begin(); it != myClass.end(); ++it)
{
std::cout << *it << std::endl;
}
return 0;
}
FAQ
基于范围的for循环
通常在遍历数组时,我们可这样使用:
void func()
{
vector<int> data ={1,2,3,4};
for(auto i = data.begin(); i != data.end(); ++i)
{
cout<<*it<<endl;
}
}
C++引入了另外一种基于范围的for循环,使得遍历更加简单
for(auto i:data)
如果你想在基于范围的for循环中使用引用,你可以通过在迭代变量前加上&来实现。这允许你直接修改迭代到的元素,而不是创建一个元素的副本。
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
for (int& x : vec)
{
x = x * 2; // 这会改变原始vector中的值
}
}