2012-03-15 53 views
1

我試圖做一個類列表,用迭代器:操作=不承認

#ifndef UTIL_H 
#define UTIL_H 

#include <iostream> 
#include <exception> 

namespace Util 
{ 

class IndexOutOfBounds : public std::exception 
{ 
    virtual const char* what() 
    { 
     return "Index out of bounds"; 
    } 
}; 

template<class T> 
class Iterator; 

template <class T> 
class ListNode 
{ 

    template<class R> 
    friend class Iterator; 
    template<class R> 
    friend class List; 

    public: 

    ListNode() 
    { 
     init(); 
    } 
    ListNode(T info) 
    { 
     init(); 
     this->info=info; 
    } 
    static void link(ListNode<T> first, ListNode<T> second) 
    { 
     first.next=&second; 
     second.prev=&first; 
    } 
    template<class R> 
    friend std::ostream& operator<< (std::ostream& out, const ListNode<R>& node); 
    template<class R> 
    friend std::istream& operator>> (std::istream& in, const ListNode<R>& node); 

    private: 

    T info; 
    ListNode<T>* next; 
    ListNode<T>* prev; 
    void init() 
    { 
     next=prev=this; 
    } 
}; 

template<class T> 
std::ostream& operator<< (std::ostream& out , const ListNode<T>& node) 
{ 
    out << node.info; 
    return out; 
} 

template<class T> 
std::istream& operator>> (std::istream& in , const ListNode<T>& node) 
{ 
    in >> node.info; 
    return in; 
} 

template <class T> 
class List 
{ 
    friend class ListNode<T>; 
    template <class R> 
    friend class Iterator; 
    private: 

    unsigned int length; 
    ListNode<T>* node; 

    public: 

    List() 
    { 
     node=new ListNode<T>(); 
     length=0; 
    } 
    unsigned int size() const 
    { 
     return length; 
    } 
    void insert(int i,T info) throw() 
    { 
     ListNode<T>* ptr=node,*next_ptr; 
     try 
     { 
      if(i>(int)length || i<0) 
       throw IndexOutOfBounds(); 
      for(int j=0;j<i;j++) 
       ptr=ptr->next; 
      next_ptr=ptr->next; 
      ptr->next=new ListNode<T>(info); 
      ptr->next->prev=ptr; 
      ListNode<T>::link(*(ptr->next),*next_ptr); 
      length++; 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void push_back(T info) throw() 
    { 
     try 
     { 
      insert(length,info); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void push_front(T info) throw() 
    { 
     try 
     { 
      insert(0,info); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void remove(int i) throw() 
    { 
     ListNode<T>* ptr=node,*next_ptr; 
     try 
     { 
      if(i>=length || i<0) 
       throw IndexOutOfBounds(); 
      for(int j=0;j<i;j++) 
       ptr=ptr->next; 
      next_ptr=ptr->next->next; 
      delete ptr->next; 
      ListNode<T>::link(*ptr,*next_ptr); 
      length--; 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void pop_back() throw() 
    { 
     try 
     { 
      remove(length-1); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    void pop_front() throw() 
    { 
     try 
     { 
      remove(0); 
     } 
     catch(IndexOutOfBounds& e) 
     { 
      throw e; 
     } 
    } 
    Iterator<T> begin() 
    { 
     Iterator<T> result; 
     result.ptr=node->next; 
     return result; 
    } 
    Iterator<T> last() 
    { 
     Iterator<T> result; 
     result.ptr=node->prev; 
     return result; 
    } 
    Iterator<T> end() 
    { 
     Iterator<T> result; 
     result.ptr=node; 
     return result; 
    } 
    template <class R> 
    friend std::ostream& operator<< (std::ostream& out , const List<R>& l); 
    template <class R> 
    friend std::istream& operator>> (std::istream& in , const List<R>& l); 
    typedef Iterator<T> iterator; 

}; 

template<class T> 
std::ostream& operator<< (std::ostream& out , const List<T>& l) 
{ 
    Iterator<T> i=l.begin(); 
    return out; 
} 

template<class T> 
std::istream& operator>> (std::istream& in , const List<T>& l) 
{ 
    for(Iterator<T> i=l.begin();i!=l.end();i++) 
     in >> *i; 
    return in; 
} 

template <class T> 
class Iterator 
{ 
    friend class List<T>; 
    friend class ListNode<T>; 
    private: 

    ListNode<T>* ptr; 

    public: 

    Iterator() 
    { 
     ptr=NULL; 
    } 
    Iterator(const Iterator<T>& i) 
    { 
     ptr=i.ptr; 
    } 
    Iterator<T>& operator= (Iterator<T> i) 
    { 
     ptr=i.ptr; 
     return *this; 
    } 
    Iterator<T>& operator++() 
    { 
     ptr=ptr->next; 
     return *this; 
    } 
    Iterator<T> operator++ (int) 
    { 
     Iterator<T> i=*this; 
     ++*this; 
     return i; 
    } 
    Iterator<T>& operator--() 
    { 
     ptr=ptr->prev; 
     return *this; 
    } 
    Iterator<T> operator-- (int) 
    { 
     Iterator<T> i=*this; 
     --*this; 
     return i; 
    } 
    T& operator*() 
    { 
     return ptr->info; 
    } 
    template<class R> 
    friend bool operator!= (Iterator<R>& i, Iterator<R>& j); 
    template<class R> 
    friend bool operator== (Iterator<R>& i, Iterator<R>& j); 

}; 

template <class T> 
bool operator!= (Iterator<T>& i, Iterator<T>& j) 
{ 
    return i.ptr!=j.ptr; 
} 

template <class T> 
bool operator== (Iterator<T>& i, Iterator<T>& j) 
{ 
    return i.ptr==j.ptr; 
} 

} 

#endif 

但我得到這些錯誤:

/home/ramy/Documents/C++/Prova/Util.h||In function ‘std::ostream&  Util::operator<<(std::ostream&, const Util::List<T>&) [with T = int]’:| 
/home/ramy/Documents/C++/Prova/main.cpp|11|instantiated from here| 
/home/ramy/Documents/C++/Prova/Util.h|218|error: passing ‘const Util::List<int>’ as ‘this’ argument of ‘Util::Iterator<T> Util::List<T>::begin() [with T = int]’ discards qualifiers| 
||=== Build finished: 1 errors, 0 warnings ===| 

有了這個主:

#include <iostream> 
#include "Util.h" 

using namespace Util; 

int main(int argc, char** argv) 
{ 
List<int> l; 
for(int i=0;i<10;i++) 
    l.push_back(i); 
std::cout << l; 
return 0; 
} 

我不是爲什麼我得到這個錯誤,它似乎像運營商=不被認爲是正確的。 這聽起來很荒唐,但當然會有解釋。

回答

1

你需要一個

ConstIterator<T> List<T>::begin() const; 
//        ^^^^^ 

與相應ConstIterator類型,以便在Util::operator<<列表可在該列表實際上迭代。非const成員函數不能用於const引用,即使引用本身是非const

當你在這,你應該定義了一堆其他const成員函數爲List<T>

0

看起來你調用非const的方法const對象上(開始())。