目录
概述
<iterator>
是 C++ STL 中的迭代器支持库,提供了一系列工具和类型,用于增强迭代器的功能。它定义了迭代器类别、适配器(如反向迭代器、插入迭代器)、流迭代器以及辅助函数,帮助开发者更方便地操作容器和流。
包含头文件
#include <iterator>
#include <iostream>
#include <vector> // 示例中常用容器
基本概念
迭代器是 STL 的核心组件,充当容器元素与算法之间的桥梁。<iterator>
提供了标准化的迭代器支持,使其更通用和灵活。
基本特性
- 类型支持:定义迭代器类别标签(如
std::forward_iterator_tag
)。 - 适配器:提供反向、插入等特殊迭代器。
- 流操作:支持输入输出流与容器的交互。
- 工具函数:如
advance
、distance
,增强迭代器操作。
基本用法
迭代器类别
C++ 定义了五种迭代器类别(通过 <iterator>
中的标签类区分):
- 输入迭代器 (
std::input_iterator_tag
):只读,单次遍历。 - 输出迭代器 (
std::output_iterator_tag
):只写,单次遍历。 - 前向迭代器 (
std::forward_iterator_tag
):读写,单向遍历。 - 双向迭代器 (
std::bidirectional_iterator_tag
):读写,双向遍历。 - 随机访问迭代器 (
std::random_access_iterator_tag
):读写,支持随机访问。
示例:
#include <iterator>
#include <list>
#include <iostream>
int main() {
std::list<int> lst = {1, 2, 3};
using Iterator = std::list<int>::iterator;
std::iterator_traits<Iterator>::iterator_category category; // 双向迭代器
std::cout << "List iterator is bidirectional" << std::endl;
return 0;
}
迭代器适配器
反向迭代器 (reverse_iterator
)
#include <iterator>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4};
std::reverse_iterator<std::vector<int>::iterator> rit(v.end());
std::cout << "Reverse: ";
for (; rit != std::reverse_iterator<std::vector<int>::iterator>(v.begin()); ++rit) {
std::cout << *rit << " "; // 输出:4 3 2 1
}
std::cout << std::endl;
return 0;
}
- 通过
std::make_reverse_iterator
或容器方法(如rbegin()
)更简便。
插入迭代器 (inserter
, back_inserter
, front_inserter
)
#include <iterator>
#include <vector>
#include <list>
#include <iostream>
int main() {
std::vector<int> v = {1, 2};
std::vector<int> src = {3, 4};
std::copy(src.begin(), src.end(), std::back_inserter(v)); // 尾部插入
std::cout << "Back insert: ";
for (int x : v) std::cout << x << " "; // 输出:1 2 3 4
std::cout << std::endl;
std::list<int> lst = {1, 2};
std::copy(src.begin(), src.end(), std::front_inserter(lst)); // 头部插入
std::cout << "Front insert: ";
for (int x : lst) std::cout << x << " "; // 输出:4 3 1 2
std::cout << std::endl;
return 0;
}
back_inserter
:尾部插入(需支持push_back
)。front_inserter
:头部插入(需支持push_front
)。inserter
:指定位置插入(需支持insert
)。
迭代器工具函数
#include <iterator>
#include <vector>
#include <iostream>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = v.begin();
std::advance(it, 2); // 前进 2 步
std::cout << "Advanced: " << *it << std::endl; // 输出:3
int dist = std::distance(v.begin(), v.end());
std::cout << "Distance: " << dist << std::endl; // 输出:5
auto next_it = std::next(v.begin(), 3); // 前进 3 步
std::cout << "Next: " << *next_it << std::endl; // 输出:4
return 0;
}
advance()
:移动迭代器指定距离。distance()
:计算两个迭代器间的距离。next()
/prev()
:返回前进/后退后的迭代器。
流迭代器
输入流迭代器 (istream_iterator
)
#include <iterator>
#include <iostream>
#include <vector>
int main() {
std::cout << "Enter numbers (Ctrl+D or Ctrl+Z to stop): ";
std::vector<int> v;
std::copy(std::istream_iterator<int>(std::cin), std::istream_iterator<int>(), std::back_inserter(v));
std::cout << "Input: ";
for (int x : v) std::cout << x << " ";
std::cout << std::endl;
return 0;
}
输出流迭代器 (ostream_iterator
)
#include <iterator>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3};
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl; // 输出:1 2 3
return 0;
}
自定义迭代器
#include <iterator>
#include <iostream>
class MyContainer {
int data[5] = {1, 2, 3, 4, 5};
public:
class Iterator {
int* ptr;
public:
Iterator(int* p) : ptr(p) {}
int& operator*() { return *ptr; }
Iterator& operator++() { ++ptr; return *this; }
bool operator!=(const Iterator& other) const { return ptr != other.ptr; }
using iterator_category = std::forward_iterator_tag;
using value_type = int;
using difference_type = std::ptrdiff_t;
using pointer = int*;
using reference = int&;
};
Iterator begin() { return Iterator(data); }
Iterator end() { return Iterator(data + 5); }
};
int main() {
MyContainer c;
for (auto it = c.begin(); it != c.end(); ++it) {
std::cout << *it << " "; // 输出:1 2 3 4 5
}
std::cout << std::endl;
return 0;
}
与其他库的对比
特性 | <iterator> | <algorithm> | 容器内置迭代器 |
---|---|---|---|
功能 | 迭代器工具 | 算法操作 | 容器遍历 |
通用性 | 高(适配所有容器) | 高(依赖迭代器) | 特定容器 |
操作范围 | 迭代器支持 | 元素操作 | 容器内元素 |
复杂度 | O(1) – O(n) | O(1) – O(n log n) | 依赖容器 |
注意事项
- 迭代器兼容性:确保迭代器类型与算法要求匹配。
- 流迭代器限制:
istream_iterator
不可重复读取。 - 自定义迭代器:需满足 STL 迭代器要求(如
iterator_traits
)。 - 性能:
distance
在非随机访问迭代器上为 O(n)。
实用示例:文件读取与处理
#include <iterator>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
int main() {
std::string input = "1 2 3 4 5";
std::istringstream iss(input);
std::vector<int> v;
// 使用输入流迭代器读取数据
std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(), std::back_inserter(v));
// 反向输出
std::cout << "Reverse: ";
std::copy(std::make_reverse_iterator(v.end()), std::make_reverse_iterator(v.begin()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl; // 输出:5 4 3 2 1
return 0;
}
小练习
问题
写一个 C++ 程序:
- 定义一个
std::vector<int>
,初始化为 {1, 2, 3, 4, 5}。 - 使用
std::reverse_iterator
输出逆序序列。 - 使用
std::distance
计算第 2 个元素到末尾的距离。
参考答案
#include <iterator>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// 逆序输出
std::cout << "Reverse: ";
for (auto it = std::make_reverse_iterator(v.end()); it != std::make_reverse_iterator(v.begin()); ++it) {
std::cout << *it << " "; // 输出:5 4 3 2 1
}
std::cout << std::endl;
// 计算距离
auto start = v.begin();
std::advance(start, 2); // 移动到第 2 个元素(索引 2,值为 3)
int dist = std::distance(start, v.end());
std::cout << "Distance from 3rd element to end: " << dist << std::endl; // 输出:3
return 0;
}
参考资料
- C++ Standard Library Reference:
<iterator>
的官方文档。
- ISO/IEC 14882:2011 (C++11 Standard)
- cppreference.com: 提供
<iterator>
的详细说明和示例。 - The C++ Programming Language (4th Edition) by Bjarne Stroustrup: C++ STL 权威书籍。
- Effective STL by Scott Meyers: STL 迭代器实用建议。
出站链接
- cppreference.com: – 官方文档和示例。
- C++ Reference: – 接口说明。
- GeeksforGeeks: Iterators in C++ STL – 教程和代码示例。
- LearnCpp: Introduction to Iterators – 初学者教程。
下一步
- 如果你想试试练习,请提交代码,我会帮你检查。
- 如果需要更深入内容(如自定义迭代器实现、与
<ranges>
对比),或设计测验题,请告诉我! - 你也可以提出具体问题,如“如何用
<iterator>
优化算法?”或“<iterator>
和<algorithm>
的协作原理?”。
现在,你想做什么?试试练习,还是有其他需求?
发表回复