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

c+中的迭代器+;底层工作 我正在研究C++中的迭代器。作者提到迭代器可以是普通的指针,但在某些情况下它们可能不同,c++,c++11,iterator,C++,C++11,Iterator,作者所说的“不同”到底是什么意思?智能指针?指针是实现迭代器的一种方法。该标准允许这样做,但它也允许其他实现,例如包含引用的对象。唯一重要的是为其声明的迭代器类别提供正确的公共接口 由于指针有运算符+++、运算符*和其他指针,它们可以充当连续集合的迭代器,例如std::vector和std::array 但是,它们不能充当(比如)链表的迭代器,因为运算符+++没有正确的语义。迭代器有不同的类别(分类): 输入迭代器 输出迭代器 前向迭代器 双向迭代器 随机存取迭代器 普通指针属于随机访问分类

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

指针是实现迭代器的一种方法。该标准允许这样做,但它也允许其他实现,例如包含引用的对象。唯一重要的是为其声明的迭代器类别提供正确的公共接口

由于指针有
运算符+++
运算符*
和其他指针,它们可以充当连续集合的迭代器,例如
std::vector
std::array


但是,它们不能充当(比如)链表的迭代器,因为
运算符+++
没有正确的语义。

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

  • 输入迭代器
  • 输出迭代器
  • 前向迭代器
  • 双向迭代器
  • 随机存取迭代器
普通指针属于随机访问分类。这意味着它具有随机访问的属性

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

Next_Location = Previous_Location + sizeof(Target_Data_Type);
内存位置取决于指针指向的数据类型

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


因此,一个重要的区别是,增加一个interator使它指向下一个项,增加一个指针使它指向下一个内存位置(根据数据类型的大小进行调整)

作者的意思是,迭代器可以实现为自定义(在某些情况下非常复杂)对象。它们不一定是指针。相反,他们认为自己的行为与他们相似(至少在某种程度上)

下面是迭代器的一个非常基本的例子,迭代器实际上做的不多。它是一个简单地迭代一系列数字的实现。关键是它显然是一个迭代器实现,但显然与指针无关

我已经自由地用调试输出加载了它,这样您就可以看到发生了什么。它提供了传统的和基于范围的迭代示例。这两种方法的输出差异是。。。有趣的是:

#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';
}
我知道这很简单,但重点是演示迭代器如何不必是指针,甚至不必使用指针。他们迭代的方式最终取决于迭代器实现本身,只要它符合它声称支持的迭代器类别的要求


希望能有所帮助。

它们可以作为索引。或者在某种深奥的哈希表实现中,一个哈希表。它们不必是指针;他们可以表现得像他们一样。例如:用户定义的具有内部状态数据的对象和它们声称提供的适当的公共运算符重载就足够了。@MicroVirus不,索引不是迭代器。Rahul,例如,它们可以是实现某些迭代器概念的用户定义类型(请参见)@juanchopanza持有对被迭代对象的引用,并且该对象中当前元素的索引不是迭代器?(可能是,我从来没有真正去深入研究C++迭代器)@ MyVixt,这并不意味着索引可以是一个迭代器。使用类会更清楚,因为我没有读过Strut这样的代码,但它不是一个很好的例子。now@rahultyagiC++中的类和结构是相同的,除了默认的访问级别之外,对于
struct
来说,默认的访问级别是
public
,对于class来说,默认的访问级别是
private
;参见,例如。
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