C ++底层工作中的迭代器

Iterators in c++ underlying working

我正在研究 C++ 中的迭代器。作者提到迭代器可以是普通的指针,但在某些情况下它们可能会有所不同。

作者所说的不同到底是什么意思?智能指针?

指针是实现迭代器的一种方式。该标准允许这样做,但它也允许其他实现,例如持有引用的对象。唯一重要的是为其声明的迭代器类别呈现正确的 public 接口。

由于指针有 operator++operator* 等,它们可以充当连续集合的迭代器,例如 std::vectorstd::array

但是,它们不能充当链表等的迭代器,因为 operator++ 没有正确的语义。

迭代器有不同的类别(分类):

  • 输入迭代器
  • 输出迭代器
  • 前向迭代器
  • 双向迭代器
  • 随机访问迭代器

普通指针属于随机访问分类。这意味着它具有随机访问的属性。

指针可以递增和递减。主要区别在于递增和递减的定义。递增的内存位置方程为:

Next_Location = Previous_Location + sizeof(Target_Data_Type);

内存位置取决于指针指向的数据类型。

Forward_Iterator派生的迭代器将指向下一项;不一定到下一个内存位置。一个例子是链表。链表中的 next 项可能在内存中的任何位置;不一定是下一个内存位置。

所以一个重要的区别是递增一个interator使其指向下一个项目递增一个指针使其指向下一个内存位置(调整对于数据类型的大小).

作者的意思是迭代器可以作为自定义(在某些情况下非常复杂)对象来实现。他们不必是指针。相反,他们归因于 行为 喜欢他们(至少在某种程度上)。

以下是一个非常 迭代器的基本示例,它并没有真正做很多事情。它是一个 input-iterator-category 实现,它简单地迭代一系列数字。关键是它显然是一个迭代器实现,但显然与指针 没有任何关系

我冒昧地用调试输出加载它,这样你就可以看到发生了什么。它提供了传统的和基于范围的迭代示例。两者的输出差异...有趣:

#include <iostream>
#include <iterator>

struct Range
{
    Range(int low, int high)
        : low(std::min(low,high))
        , high(std::max(low,high))
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
    }

    // custom iterator for our Range type
    struct iterator : public std::iterator<std::input_iterator_tag, int, std::ptrdiff_t, int*, int>
    {
        friend struct Range;

        iterator& operator ++()
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
            ++myvalue;
            return *this;
        }

        iterator operator ++(int)
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
            return iterator(range, myvalue++);
        }

        int operator*() const
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
            return myvalue;
        }

        bool operator ==(const iterator& it) const
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
            return myvalue == it.myvalue;
        }

        bool operator !=(const iterator& it) const
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
            return myvalue != it.myvalue;
        }

    private:
        iterator(Range& range, int value)
            : range(range)
            , myvalue(value)
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
        }

        Range& range;
        int myvalue;
    };

    iterator begin()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
        return iterator(*this, low);
    }

    iterator end()
    {
        std::cout << __PRETTY_FUNCTION__ << '\n';
        return iterator(*this, high+1);
    }

private:
    int low, high;
};


int main()
{
    Range range(1,5);

    // traditional iteration
    for (Range::iterator it = range.begin(); it != range.end(); ++it)
        std::cout << *it << '\n';
    std::cout << '\n';

    // C++11 range-based iterator
    for (auto n : range)
        std::cout << n << '\n';
    std::cout << '\n';
}

输出

Range::Range(int, int)
Range::iterator Range::begin()
Range::iterator::iterator(Range &, int)
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
1
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
2
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
3
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
4
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
5
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const

Range::iterator Range::begin()
Range::iterator::iterator(Range &, int)
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
1
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
2
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
3
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
4
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
5
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const

我知道这很简单,但重点是演示迭代器如何不必是指针,甚至 使用 指针。他们如何迭代他们正在迭代的任何内容最终将取决于迭代器实现本身,只要它符合它声称支持的迭代器类别的要求。

希望对您有所帮助。