为什么“!=”与迭代器一起使用?

我习惯于这样写循环:

for (std::size_t Index = 0; Index < Foo.Size(); Index++) { // Do stuff with Foo[Index]. } 

但是当我在其他代码中看到迭代器循环时,它们看起来像这样:

 for (Bar::Iterator Iterator = Foo.Begin(); Iterator != Foo.End(); Foo++) { // Do stuff with *Iterator. } 

我发现Iterator != Foo.End()是有争议的。 Iterator增加一个以上也是危险的。

使用Iterator < Foo.End()似乎更“正确”,但我从来没有在真正的代码中看到这一点。 为什么不?

所有的迭代器都是相等的。 只有随机访问迭代器是关系可比的。 input迭代器,前向迭代器和双向迭代器不具有关联性。

因此,使用!=的比较比使用<的比较更具通用性和灵活性。


有不同的迭代器类别,因为不是所有的元素范围都有相同的访问属性。 例如,

  • 如果你有一个迭代器到一个数组(一个连续的元素序列),关系比较它们是微不足道的。 你只需要比较指向元素的指针(或指向它们的指针,因为迭代器可能只包含指向元素的指针)。

  • 如果你有迭代器进入链表,并且你想testing一个迭代器是否“小于”另一个迭代器,你必须从一个迭代器中遍历链表的节点,直到你到达另一个迭代器或者到达结束的名单。

规则是迭代器上的所有操作应该具有恒定的时间复杂度(或者至less是次线性时间复杂度)。 您可以随时执行等式比较,因为您只需比较迭代器是否指向相同的对象。 所以,所有的迭代器都是相等的。


而且,你不允许迭代器超过它所指向的范围的末尾。 所以,如果最终发生在it != foo.end()it < foo.end()不一样的情况下,你已经有了未定义的行为,因为你已经迭代了超过范围的末尾。

指向数组的指针也是如此:你不能增加一个指针超过数组的末尾; 这样做的程序performance出未定义的行为。 (指数显然不是这样,因为指数只是整数。)

某些标准库实现(如Visual C ++标准库实现)具有有用的debugging代码,当您使用这样的迭代器执行某些非法操作时会引发一个断言。

简短的回答:因为Iterator不是一个数字,所以它是一个对象。

较长的答案:有比线性数组更多的集合。 例如,树和散列并不真正适合“这个指数在这个其他指数之前”。 例如,对于一棵树,两个生活在不同分支上的指标。 或者,哈希中的任何两个索引 – 他们都没有任何顺序,所以你施加的任何顺序都是任意的。

你不必担心“缺less” End() 。 这也不是一个数字,它是代表收集结束的一个对象。 有一个迭代器越过它,而事实上它不能。

 bool solve(){ map<int,int>::iterator a,b; return a<b; } 

结果:

错误:'a <b'中的'operator <'不匹配