重载迭代器:c++语义问题

Overloading Iterator: C++ Semantics Question

本文关键字:语义 问题 c++ 迭代器 重载      更新时间:2023-10-16

请注意这段代码不是我写的。否则我也不会问这个问题。这要归功于杰瑞·科芬。无论如何,代码通过重载std::iterator<> .

我将首先发布代码,然后我会给出我所看到的解释。如果有一位c++专家能纠正我的错误,我将不胜感激。

static const int N = 10;
template <class T>
class sequence : public std::iterator<std::forward_iterator_tag, T>
{
private:
    T val;
public:
    sequence(T init) : val(init) { }
    T operator *( ) { return val; }
    sequence &operator++( ) { ++val; return *this; }
    bool operator != ( const sequence &other ) { return val != other.val; }
};
void foo( )
{
    typedef std::vector<int> graph;
    graph id1( gen_seq(0), gen_seq( N ) );
    display( id1 );                             /* Not declared */
}
/* displays: 0 1 2 3 4 5 6 7 8 9 */

所以当看到这个时,我看到你创建了一个包含值的类。现在将其中两个传递给vector的构造函数,该构造函数可以接受两个迭代器。现在,每次vector的构造函数对"序列"使用++操作符时,它都会对迭代器内部的值加1。技术上,你可以这样写:

graph id1( gen_seq( 0 ), gen_seq( 0 ) );

,这将产生相同的序列,对吗?或者是!=运算符检查是否0没有变成n。任何关于这方面的输入都会有很大帮助。我刚刚读完Stroustrup的c++编程语言第3版,他在书中提到了迭代器,但是继承迭代器并不是一个大的话题,我也不完全理解。有点像我做了他所有的练习,因为我记得他有几次要求重载迭代器

你并没有重载一个迭代器;您正在编写自己的迭代器,其中涉及重载一些操作符。

std::vector构造函数实际上是这样的:

template <typename ForwardIterator>
vector(ForwardIterator first, ForwardIterator last)
{
    for (ForwardIterator it = first; it != last; ++it)
        push_back(*it);
}

(实际上,它比这更复杂,因为它需要更有效地处理随机可访问的范围,但对于前向可迭代的范围,它就是这样做的。)

可以看到,该构造函数对迭代器执行了三个操作:对其解引用(*it),对其加1 (++it),并执行不等式比较(it != last)。当它执行上述每一项操作时,它调用在自定义迭代器类中定义的相应操作符。

graph id1( gen_seq( 0 ), gen_seq( 0 ) );将工作,但它不会给出相同的结果:它将使id1为空。根据前几段的解释,你明白为什么了吗?

没有graph id1( gen_seq( 0 ), gen_seq( 0 ) );会生成一个零大小的向量。你使用!=的第二个解释更接近。如果你理解矢量代码可能会有所帮助。大概是这样的

template <class II>
vector::vector(II first, II last)
{
  while (first != last)
  {
    push_back(*first);
    ++first;
  }
}

可以看到,!=被用来决定何时停止向vector中添加元素。

(由于各种技术和效率原因,实际的矢量代码可能比这复杂得多,但上面给出了适用于您的情况的本质)。