迭代器和指针有何关系?
使用迭代器的代码看起来非常类似于使用指针的代码。迭代器是一些晦涩的类型(例如 std::vector
)。
我不明白的是迭代器和指针如何相互关联 - 迭代器是指针的包装器,具有重载操作以前进到相邻元素还是其他东西?
Code with iterators looks pretty much like code with pointers. Iterators are of some obscure type (like std::vector<int>::iterator
for example).
What I don't get is how iterators and pointer are related to each other - is an iterator a wrapper around a pointer with overloaded operations to advance to adjacent elements or is it something else?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
迭代器是指针的泛化。
迭代器(取决于变体)必须实现 * 和 ++
因此指针就是迭代器。但反过来也不一定。
如果你想迭代一个复杂的结构(一棵树,一个图......),迭代器将不仅仅是一个指针,并且不会对内存中的某些实际位置进行任何引用。
Iterators are a generalization of pointers.
An iterator (depending on the variants) have to implement * and ++
So a pointer IS an iterator. But not necessarily the other way round.
If you want to iterate over a complex structure (a tree, a graph...), the iterator will be much more than a pointer, and doesn't make any reference to some actual place in the ram.
迭代器是重载某些运算符的对象,因此用法看起来就像它们是指针。这在给定迭代器类别的能力范围内。随机访问迭代器看起来完全像指针,其他类型的迭代器不提供某些操作(例如双向的
list::iterator
没有运算符+=
其中许多需要随机访问)。至于“晦涩的名称”,使用普通指针作为迭代器并非完全不可想象:
Iterators are objects that overload certain operators, so the usage would look like they were pointers. That's within the capabilities of a given iterator category. Random access iterators look entirely like pointers, other types of iterators don't provide some operations (e.g
list<X>::iterator
which is bidirectional doesn't have operator+=
among many others that would require random access).As to the "obscure names", it is not completely unthinkable to use a plain pointer for an iterator:
从概念上讲,是的——但它们不必是指针。它们的内部结构和功能将取决于它们“包装”的数据结构。
这就是为什么有不同的迭代器“类”。例如,单向、双向、随机访问等。
有些能够支持多个类别。
例如,如果内部结构是红黑树或链表,则迭代器可能是双向的,但不是随机访问的。如果它们包装一个向量(作为数组实现),您将拥有随机访问和双向。
Conceptually, yes -- but they need not be pointers. Their internals and capabilities will depend on the data structure they "wrap".
That is why there are different "classes" of iterators. E.g. Unidirectional, Bidirectional, RandomAccess, etc.
Some are capable of multiple classes.
E.g. if the internal structure is a Red-Black tree or Linked List, the iterators might be Bidirectional, but not RandomAccess. If they wrap a vector (implemented as an array), you'll have RandomAccess and Bidirectional.
迭代器只是一种提供迭代器所需接口的类型 - 对于不同类型的迭代器,这些接口是不同的,并在 C++ 标准(迭代器要求)第 24.1 节中指定。
迭代器的实现方式取决于它们迭代的内容 - 对于向量,它们通常是指向数组的单个指针的包装器(无论如何在发布版本中),对于更复杂的容器,它们有更复杂的实现。对于开放式范围,它们将包含用于生成元素的任何算法的状态。
请注意,指向数组中元素的指针满足随机访问迭代器的要求,因此在某种程度上它们是可以互换的。
An iterator is just a type that provides the interface required for iterators - these are different for the different types of iterators and are specified in section 24.1 of the C++ standard (Iterator Requirements).
How iterators are implemented is dependent on what they iterate over - for vectors they are commonly a wrapper around a single pointer to an array (in release builds anyway), for more complex containers they have a more complicated implementation. For open ended ranges they will contain the state of whatever algorithm is beimng used to generate the elements.
Note that a pointer to an element in an array meets the requirements of a random access iterator, so to some extent they are interchangeable.
正如所说:迭代器是指针的泛化。每个指针都是一个迭代器,但并非每个迭代器都是指针(尽管大多数非指针迭代器都包含指针)。
迭代器是一种接口(或概念)。我们可以如下定义最小迭代器接口:
但是迭代器没有真正的抽象基类。所有以迭代器为参数的函数都是模板函数,并且迭代器参数的类型是使用模板定义的。这称为静态多态性。我们可以使用
std::vector
构造函数 作为示例:由于
InputIt
是使用模板定义的类型,并且由于所有指针都支持operator++()
和operator*()
,因此所有指针可以用作迭代器。例如:or
由于迭代器只是一个抽象接口,因此指针并不是迭代器的唯一示例。任何重写
operator++()
和operator*()
的类都可以用作迭代器。通常容器使用自定义类作为迭代器而不是指针。但有些函数仍然使用指针作为迭代器。一个例子是std::begin
和 < a href="https://en.cppreference.com/w/cpp/iterator/end" rel="nofollow noreferrer">std::end
静态数组函数:有是不同类型的迭代器。最高级的迭代器类型是随机访问迭代器。除了
operator++()
和operator*()
之外,它还支持许多其他操作,例如向后推进 (operator--()
) 或向前推进许多元素单步(operator+=(size_t n)
)。指针是随机访问迭代器。这就是指针和迭代器的关系。
继续。迭代器是允许迭代某些元素集合的对象类。指针只是迭代器的一个示例,但还有其他迭代器。
As it was said: iterators are a generalization of pointers. Every pointer is an iterator but not every iterator is a pointer (although most of non-pointer iterators contain pointers within).
Iterator is kind of interface (or concept). We could define the minimum iterator interface as follows:
But there is no real abstract base class for iterators. All functions that take iterators as parameters are template functions, and types for iterator parameters are defined using templates. This is called static polymorphism. We can use
std::vector
constructor as an example:Since
InputIt
is a type defined using template and since all pointers supportoperator++()
andoperator*()
, all pointers can be used as iterators. For example:or
Since iterator is just an abstract interface, pointers are not the only example of iterators. Any class that overrides
operator++()
andoperator*()
can be used as an iterator. And usually containers use custom classes as iterators instead of pointers. But some functions still use pointers as iterators. An example isstd::begin
andstd::end
functions for static arrays:There are different types of iterators. The most advanced type of iterator is Random Access Iterator. Besides
operator++()
andoperator*()
it supports many other operations like advancing backward (operator--()
) or advancing many elements forward at single step (operator+=(size_t n)
). Pointers are Random Access Iterators.This is how pointers and iterators are related.
Resume. Iterators are class of objects that allows to iterate through some collection of elements. Pointers are just an example of iterators but there are others.