关于C ++迭代器的问题


Questions about C++ iterators

在C++中,为什么我们不能使用">"或"<"来比较初始化程序、转发迭代器和双向迭代器?但是,我们可以将RandoAccessIterator与">"或"<"进行比较,例如std::vector。这背后的原因是什么?

另外,为什么我们不能迭代程序的内容呢?例如"cout<

一般来说,迭代器和指针之间的内在区别是什么?我曾经认为它们是相似的,但我想我必须理解这一点,以便理解C++的下一个层次。

问题2:感谢大家的精彩回答。关于迭代器,我还有一个问题。为什么当迭代器出界外时,C++会打印出"50397953"?它不应该打印类似于"空"或"0"的内容吗?


std::list有双向迭代器,要求它们具有可比性没有任何意义。甚至不清楚如何实现std::list以符合这样的要求。然而,由于随机访问迭代器支持减法,很明显我们可以比较它们。

为什么不能打印迭代器的值?一般来说,是否支持这样的操作取决于作者。许多迭代器基本上都是作为指针或围绕指针的包装器实现的——为它们提供operator<<,仅仅打印出所指向对象的地址并不能给用户带来任何好处。

至于迭代器和指针之间的区别,指向对象的指针是一种特定的随机访问迭代器,但是迭代器也可以是类类型,只要它们满足迭代器的要求。


既有严格的、正式的解释,也有实际的解释。

严格的正式解释

因为它是如何在C++中指定的。

实际解释

根据定义,向量总是存储在连续内存中。迭代器或多或少是一个指针。因此,通过比较实际的底层内存地址,可以定义哪个指针比另一个指针"小"或"大"。

另一方面,列表或集合中的每个元素都可以存储在任何地方。每个元素都是独立实例化的。列表中某个特定元素的迭代器引用的内存位置可能比同一列表中另一个元素的不同迭代器少,但实际元素可能在实际列表中的另一个元素之后。给定一个列表中的两个迭代器,就不能立即确定哪个更接近列表的开头或结尾。请注意,在列表中插入和删除元素不会使现有的列表迭代器失效,因为列表中的每个元素都是独立实例化的。

std::ostream上不能与operator<<一起使用迭代器的实际原因是,当然,这个重载没有定义。请注意,您可以始终执行以下操作:

1
cout << &*itr << endl;

这将格式化被引用元素的实际内存地址。但无论如何,这是有可疑用途的。这几乎毫无意义。


我不会回答你问题的第一部分,因为我同意你所说的话,但我会回答你另外两部分,增加一些细节。我从最容易解释的部分开始。

In general, what is the intrinsic difference between iterators and pointers? I used to think they are similar, but I guess I have to understand this in order to get to the next level of understanding c++.

迭代器是指针的泛化。

您还可以查看GitHub上的迭代器实现

Also, why can't we cout iterators' content? such as"cout << itr << endl;" wouldn't work. What is the reason behind this? Iterators are a lot like pointers, but we can cout pointers but not iterators, why?

所以,据我所知,内部发生的事情是迭代器是一个类,它有一个字段存储指向一个项的指针。"*"运算符被覆盖,并返回存储在指针地址的值。