C++自定义容器能否适配使用标准迭代器替代自定义实现?
你对std::iterator的作用存在根本误解:std::iterator只是一个用来批量定义迭代器所需嵌套类型别名的空基类,本身没有任何成员变量、运算符实现,完全不能直接作为迭代器类型使用。
你之前直接通过using将std::iterator的实例定义为BufferIterator,本质是把一个没有任何状态的空结构体当迭代器用,自然会报缺少运算符的错误。就算你在命名空间下额外补全运算符重载,这个类型也没有存储内存地址的成员变量,根本无法实现迭代器的遍历、解引用逻辑,这条路完全走不通。
另外你之前尝试写的全局operator!=不生效,一是因为ADL查找规则不会在你自定义的命名空间里找std命名空间下类型的运算符重载,二是这个类型本身没有可比较的内部状态,就算重载被匹配到也没法实现正确的比较逻辑。
你的自定义PtrIterator本质是对连续存储的uint8_t内存地址的包装,而C++原生指针天然满足随机访问迭代器的全部标准要求,完全不需要额外写自定义迭代器类,直接用原生指针即可,零开销、完全兼容所有STL算法,适配你的VS2013 v120_xp工具集没有任何问题:
#include <cstdint> #include <cstddef> // 原生uint8_t指针直接作为迭代器,自带所有迭代器能力 using BufferIterator = uint8_t*; using ConstBufferIterator = const uint8_t*; class Buffer { public: // 保持原有接口不变,begin/end直接返回内部内存块的起止地址即可 BufferIterator begin() const; BufferIterator end() const; // 建议补充const迭代器接口,符合标准容器的通用惯例 ConstBufferIterator cbegin() const; ConstBufferIterator cend() const; };
原生指针作为迭代器天然支持你原有自定义迭代器的所有操作:
- 前缀/后缀自增、自减运算
- 加减偏移量、两个迭代器相减计算距离
- 解引用、指针成员访问
- 所有相等、大小比较运算
- 自动满足STL对迭代器的类型别名要求,可以直接传入
std::copy、std::find、std::sort等所有标准算法使用。
如果你因为特殊原因必须保留类形式的迭代器(比如后续要加遍历校验逻辑),也应该继承std::iterator实现完整的迭代器类,而不是直接用std::iterator作为迭代器类型。另外注意你原来的PtrIterator实现有一个bug:后缀自增运算符的返回值错误,原有写法直接返回pos_++得到的T*类型,没有包装为迭代器对象,正确写法应该是:
iterator operator++(int) // 后缀自增修正 { iterator tmp(*this); ++pos_; return tmp; }
另外C++17标准已经将std::iterator标记为废弃,新代码更推荐直接手动定义迭代器需要的嵌套类型别名,或者直接用原生指针处理连续内存场景。
内容的提问来源于stack exchange,提问作者qloq

