为什么std::multiset迭代器使用++it合法但it+1不合法?
int main(){ multiset<string> graph; graph.insert("a"); graph.insert("b"); multiset<string>::iterator it = graph.begin(); cout << *(it + 1) // Wrong cout << *++it; // True }
操作合法性差异原因
二者的合法性差异核心原因是 multiset 的迭代器属于双向迭代器,不支持随机访问类的算术运算。
迭代器能力分类差异
C++ 标准库按支持的操作能力把迭代器分成多个类别,和本问题相关的两类迭代器能力如下:
- 随机访问迭代器(比如
vector、array的迭代器、原生指针):支持直接偏移运算,it + n、it - n都是合法操作,可以一步跳转到偏移n个位置的元素 - 双向迭代器(比如
multiset、set、list、map的迭代器):仅支持逐位前后移动,只能用++it/it++向后走一位、--it/it--向前走一位,没有定义+/-算术运算符
底层实现逻辑差异
multiset 底层一般用红黑树实现,所有节点在内存中不是连续存储的,没法通过迭代器的基地址加偏移量直接算出偏移n个位置的节点地址,只能顺着节点内部的后继/前驱指针逐个遍历移动。
你认为的「it + 1和++it最终指向位置一致」只是逻辑结果上的巧合,二者的底层实现逻辑完全不同:
++it是双向迭代器的标准合法操作,内部逻辑就是顺着红黑树的后继指针找到下一个节点,符合实现要求it + 1要求迭代器支持一步计算偏移1位的地址,这个操作对非连续存储的红黑树没有通用高效的实现方式,C++标准也没有要求双向迭代器重载operator+,因此编译器会直接报错。
内容的提问来源于stack exchange,提问作者o o
相关产品推荐
相关产品推荐

