迭代器模式在C++中本质是遵循编译期约定而非机械实现GoF四要素:自定义容器只需提供begin()/end(),返回支持operator*, operator++, operator!=等操作的类型,即可无缝兼容range-for和STL算法;关键在于满足LegacyIterator概念、正确定义const_iterator及类型特征(value_type等),而非抽象接口继承。

迭代器模式在C++里不是靠“实现模式”而是靠遵循约定
标准库容器(std::vector、std::list等)的begin()和end()返回的类型就是迭代器,它们本身不叫“迭代器模式”,而是通过定义operator++、*operator*、operator!=等让编译器能用for (auto it = c.begin(); it != c.end(); ++it)这种写法。你不需要手动套GOF四要素——重点是让自定义容器支持range-based for和STL算法。
让自定义容器支持for (auto& x : container)
只需在类里提供begin()和end()成员函数,返回能解引用、自增、比较的类型。这个返回类型可以是裸指针(比如数组封装),也可以是自定义结构体:
class IntRange {
int start_, end_;
public:
IntRange(int s, int e) : start_(s), end_(e) {}
struct iterator {
int val;
iterator(int v) : val(v) {}
int& operator*() { return val; }
iterator& operator++() { ++val; return *this; }
bool operator!=(const iterator& other) const { return val != other.val; }
};
iterator begin() { return iterator(start_); }
iterator end() { return iterator(end_); }
};
注意:iterator必须定义operator!=(不是==),因为range-based for底层用的是!=判断终止;operator++要返回iterator&(前缀形式),否则++it无法链式调用。
为什么不能只写operator++(int)后置递增?
STL算法(如std::find、std::sort)内部大量使用前缀++it。如果只实现后置版本iterator operator++(int),会导致编译失败或隐式转换开销。常见错误现象:
-
error: no match for 'operator!='—— 忘了定义operator!=,或参数是const不匹配 -
error: use of deleted function 'iterator::iterator(const iterator&)'—— 自定义迭代器含非拷贝成员(如unique_ptr),但STL要求迭代器可拷贝 - range-for循环只执行一次 ——
end()返回值没和begin()同类型,或operator!=逻辑反了
需要区分const_iterator吗?
如果你的容器支持const对象遍历(比如const IntRange r{1,5}; for (auto x : r)),就必须提供cbegin()/cend()或const_iterator类型的begin()/end()重载。否则会触发隐式转换或编译失败。标准做法是:
- 把
iterator设为内部类,const_iterator复用逻辑但operator*返回const int& - 或者用模板参数控制是否
const,避免代码重复 - 别忘了
typedef或using声明value_type、difference_type等——虽然range-for不强制要求,但想兼容std::distance就得补全
真正容易被忽略的是:迭代器类型必须满足LegacyIterator概念(C++17前)或input_iterator_tag等分类标签,否则std::advance之类函数无法特化,运行时可能退化成线性复杂度。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











