C++ iterator iterator

1. Introduction to iterators

In C++, an iterator (iterator) is a general abstraction for traversing and accessing elements in containers (eg std::vector, , std::list, etc.). std::mapIterators provide a unified interface so that different types of containers can be traversed and manipulated in a similar manner.

Most C++ containers provide iterators for traversing the elements in the container. For example, std::vectorand std::dequeprovide random access iterators, std::listprovide bidirectional iterators, std::setand std::mapprovide bidirectional iterators.

Two, iterator classification

Iterators are similar to pointers in that the pointed-to element can be accessed by dereferencing and moved by increment or decrement operators. The C++ standard library provides various types of iterators, which can be divided into the following categories according to the supported operations and characteristics:

  1. Input Iterator: A read-only iterator that supports forward movement, dereferencing, and equality/inequality comparisons. Algorithms suitable for single-pass scans.
  2. Output Iterator: A write-only iterator that supports forward movement and dereference assignment. Algorithms suitable for single-pass output.
  3. Forward Iterator (Forward Iterator): supports read and write operations, and can only move forward. Algorithms for multi-pass scans.
  4. Bidirectional Iterator (Bidirectional Iterator): supports read and write operations, and can move forward and backward. Suitable for algorithms that require reverse traversal.
  5. Random Access Iterator (Random Access Iterator): supports read and write operations, and can perform arbitrary jumps. Suitable for algorithms that require random access.

Third, the use of iterators

Container classes provide methods to obtain and manipulate iterators, such as:

  1. begin(): Returns an iterator pointing to the first element in the container.
  2. end(): Returns an iterator pointing to the last element in the container.
  3. rbegin(): Returns a reverse iterator pointing to the last element in the container (containers of bidirectional iterators and random access iterators only).
  4. rend(): Returns a reverse iterator pointing to the front of the first element in the container (containers of bidirectional iterators and random access iterators only).

When we need to traverse the container, we can use these methods provided by the container to get the iterator, and then use the iterator to access and manipulate the elements in the container.

Here is std::vectoran example of traversing a container using iterators:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // 使用 auto 关键字简化迭代器类型声明
    for (auto it = numbers.begin(); it != numbers.end(); ++it) {
        std::cout << *it << std::endl; // 输出 numbers 容器中的每个元素
    }

    return 0;
}

In this example, numbers.begin()an iterator pointing to the first element in the container is returned, and an numbers.end()iterator pointing past the last element in the container is returned. By incrementing the iterator ++it, we can iterate over all elements in the container.

Fourth, iterator principle

The reason iterator objects are associated with containers lies in the design and implementation of iterator objects. An iterator object usually stores information related to a specific container instance, such as a pointer to an element in the container or other data representing the current position. With this information, iterator objects can locate and access elements in the container. While an iterator object is self-contained, it is closely tied to a particular container instance because it needs to know the internal structure of the container to perform traversal and access operations.

When you get an iterator using a container's member functions (eg begin(), , etc.), those functions create an iterator object associated with the container instance. end()This iterator object stores enough information to traverse elements within the container.

Take std::vectorfor example , when you call std::vector<T>::begin(), it returns an iterator pointing to the first element in the container. This iterator usually contains a pointer to the first element inside. When you increment an iterator (such as ++it), this pointer moves according to the layout and type of elements in the container to point to the next element. In this way, the iterator can perform traversal and access operations according to the structure of the container.

It should be noted that the association of the iterator to the container is established at runtime, so the iterator object needs to be kept in sync with the container from which it was created. If the container changes (such as adding, deleting elements, etc.) during the existence of the iterator, it may cause the iterator to become invalid. In this case, continuing to use the invalidated iterator may result in undefined behavior. Therefore, when using iterators, make sure to handle these situations correctly, such as updating the iterator in time when the container changes.

Guess you like

Origin blog.csdn.net/2201_75772333/article/details/130618990