Skip to content

iterator — 迭代器

迭代器是 STL 的粘合剂,连接容器与算法。理解迭代器类别和自定义迭代器,是深度使用 STL 的关键。

迭代器类别

cpp
#include <iterator>

// 迭代器层次(能力从弱到强)
// InputIterator      — 单次遍历,只读(istream_iterator)
// OutputIterator     — 单次遍历,只写(ostream_iterator)
// ForwardIterator    — 多次遍历,读写(forward_list)
// BidirectionalIterator — 双向(list, map, set)
// RandomAccessIterator  — 随机访问(vector, deque, array)
// ContiguousIterator    — 连续内存(C++20,vector, array, string)

// 检查迭代器类别
static_assert(std::random_access_iterator<std::vector<int>::iterator>);
static_assert(std::bidirectional_iterator<std::list<int>::iterator>);
static_assert(std::forward_iterator<std::forward_list<int>::iterator>);

迭代器操作

cpp
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = v.begin();

// 所有迭代器
++it;           // 前进一步
*it;            // 解引用

// 双向迭代器
--it;           // 后退一步

// 随机访问迭代器
it += 2;        // 前进多步
it -= 1;        // 后退多步
it[2];          // 下标访问
it2 - it;       // 距离
it < it2;       // 比较

// 通用操作(适用于所有迭代器)
std::advance(it, 3);                    // 前进 n 步(双向可负数)
auto dist = std::distance(v.begin(), v.end());  // 计算距离
auto next_it = std::next(it, 2);        // 返回前进 n 步的迭代器
auto prev_it = std::prev(it, 1);        // 返回后退 n 步的迭代器

特殊迭代器

cpp
#include <iterator>

// 插入迭代器
std::vector<int> src = {1, 2, 3};
std::vector<int> dst;

std::copy(src.begin(), src.end(), std::back_inserter(dst));   // 尾部插入
std::copy(src.begin(), src.end(), std::front_inserter(dst));  // 头部插入(list)
std::copy(src.begin(), src.end(), std::inserter(dst, dst.begin() + 1));  // 指定位置

// 流迭代器
#include <sstream>
std::istringstream iss("1 2 3 4 5");
std::vector<int> nums(std::istream_iterator<int>(iss), {});

std::copy(nums.begin(), nums.end(),
          std::ostream_iterator<int>(std::cout, " "));  // 输出到流

// 反向迭代器
for (auto it = v.rbegin(); it != v.rend(); ++it) {
    std::cout << *it << " ";  // 5 4 3 2 1
}

// move 迭代器(移动而非拷贝)
std::vector<std::string> src_str = {"hello", "world"};
std::vector<std::string> dst_str;
std::copy(std::make_move_iterator(src_str.begin()),
          std::make_move_iterator(src_str.end()),
          std::back_inserter(dst_str));

自定义迭代器

cpp
// 实现一个范围迭代器
class Range {
    int start_, end_, step_;

public:
    Range(int start, int end, int step = 1)
        : start_(start), end_(end), step_(step) {}

    struct Iterator {
        int current, step;
        using iterator_category = std::forward_iterator_tag;
        using value_type = int;
        using difference_type = std::ptrdiff_t;
        using pointer = const int*;
        using reference = int;

        Iterator(int c, int s) : current(c), step(s) {}
        int operator*() const { return current; }
        Iterator& operator++() { current += step; return *this; }
        Iterator operator++(int) { auto tmp = *this; ++*this; return tmp; }
        bool operator==(const Iterator& o) const { return current >= o.current; }
        bool operator!=(const Iterator& o) const { return !(*this == o); }
    };

    Iterator begin() const { return {start_, step_}; }
    Iterator end()   const { return {end_, step_}; }
};

// 使用
for (int i : Range(0, 10, 2)) {
    std::cout << i << " ";  // 0 2 4 6 8
}

// 与 STL 算法配合
Range r(1, 100);
int sum = std::accumulate(r.begin(), r.end(), 0);

关键认知

迭代器类别决定了哪些算法可以使用。std::advance/std::distance/std::next/std::prev 是通用迭代器操作,比直接 += 更安全(适用于所有迭代器类别)。自定义迭代器需要定义五个类型别名(iterator_category 等)才能与 STL 算法配合。

系统学习 C++ 生态,深入底层架构