自定义迭代器上的前缀和后缀++也是如此

Vul*_*our 2 c++ iteration iterator

首先,我对C++很新,所以如果这是一个初学者编码错误,那么我很抱歉.

我目前正在为我在学校完成的家庭作业制作图表课程.我应该能够在集合,数组和链表中存储边缘.正如我在一个单独的类中完成了所有这些,我现在正试图通过模板化使它们全部工作.一切正常,即ie.std :: set,但是当我使用自己的链表实现时,它会以某种方式失败 - 看起来我的迭代器在某处乱了,前缀和后缀运算符都会导致相同的行为(在for循环中).我还要补充一点,我没有使用std :: list,因为我应该自己实现链表.

我目前的迭代器实现:

template<typename T>
class Iterator{
    public: node<T>* pointer;
    public:
        Iterator(): pointer(0){}
        Iterator(node<T>* _pointer): pointer(_pointer){}

        Iterator<T> operator++()    { pointer = pointer->next; }
        Iterator<T> operator++(int) { pointer = pointer->next; }

        bool operator!=(Iterator<T> rval){ return !(pointer == rval.pointer); }
        bool operator==(Iterator<T> rval){ return (pointer == rval.pointer); }

        node<T>* operator()(){ return pointer; }

        T operator*(){ return pointer->data; }

};
Run Code Online (Sandbox Code Playgroud)

单链表节点:

template <typename T>
struct node{
    node(): next(0){}
    node(T val): data(val), next(0){}
    node(node<T>* _next): data(0), next(_next){}
    node(T val, node<T>* _next): data(val), next(_next){}

    T data;
    node<T>* next;
};
Run Code Online (Sandbox Code Playgroud)

以及我的列表类如何实现begin()和end():

typedef Iterator<T> iterator;
iterator  begin()   { return iterator(new node<T>(b)); }
iterator  end()     { return iterator(); } 
Run Code Online (Sandbox Code Playgroud)

请注意,b指向链接列表中的第一个元素

最后我是如何访问元素的(这是在包含列表的不同类中):

void tree_recurse_f(int node, std::ofstream* file, int level = 0){
   [some output code here]
   typename T::iterator it;
   for (it = Database[node].first.begin(); it != Database[node].first.end(); ++it){
      tree_recurse_f(*it, file, (level+1));
   }
}
Run Code Online (Sandbox Code Playgroud)

Database是一个std::map<int,std::pair<>>并.first指向由T(set,list或vector)指定的类型

现在来问题:

  1. 不知何故,对于列表的当前实现begin(),它指向输出函数中的空节点(++ it,并且它导致同样的事情)
  2. 更改begin()to return iterator(b)似乎删除了for循环中的错误,尽管++ it和it ++都会导致同样的事情
  3. 我通过仅测试列表类来设法发现这两个错误 - 如果我将它实现到图形类中,它会在输出函数中输入一个永无止境的循环(*它总是指向0并且似乎不会随着+而增加+ IT)

对我来说看起来像迭代器的一些奇怪的东西(尤其是单独它可以工作的事实,但在其他类中它没有)

//如果有人好奇我会松散地关注http://www.cplusplus.com/articles/Lw6AC542/上的链表教程

And*_*owl 6

您的前缀和后缀运算符执行相同的操作,因为您将它们定义为执行相同的操作:

Iterator<T> operator++()    { pointer = pointer->next; }
Iterator<T> operator++(int) { pointer = pointer->next; }
Run Code Online (Sandbox Code Playgroud)

代码是相同的,但最重要的是,它有未定义的行为,因为你的函数应该返回一个类型的值Iterator<T>,而不是什么都不返回.根据C++ 11标准的第6.6.3/2段:

[...]离开函数末尾相当于没有值的返回; 这会导致值返回函数中的未定义行为.

您应该将前缀迭代器更改为以下内容:

Iterator<T> operator++() 
{ 
    pointer = pointer->next; 
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

你的postfix迭代器就是这样的:

Iterator<T> operator++(int) 
{ 
    node<T>* previous = pointer;
    pointer = pointer->next; 
    return Iterator<T>(previous);
}
Run Code Online (Sandbox Code Playgroud)

另外,如果我理解你的设计,我真的不认为你应该这样做:

iterator begin() { return iterator(new node<T>(b)); }
Run Code Online (Sandbox Code Playgroud)

我宁愿这样做:

iterator begin() { return iterator(b); }
Run Code Online (Sandbox Code Playgroud)