2016-01-14 71 views
0

我想通過鏈表實現通用映射。 我一直試圖重載++運算符來移動一個迭代器通過一個列表,但我有問題,使用新的運算符。如何使用迭代器重載增量運算符

template <class KeyType, class ValueType, class CompareFunction = std::less<KeyType> > 
class MtmMap { 
    public: 
     class Node{ 
      public: 
       const Pair* data; 
       Node* next; 
       Node() 
        : data(NULL),next(NULL){} 
       Node(const Pair pair){ 
        data=new Pair(pair); 
        data=&pair; 
        next=NULL; 
       } 
      }; 
      Node* iterator; 
      // ... 
}; 

這裏是超載:

Node* operator++(){ 
    iterator=iterator->next; 
    return iterator; 
} 

我想用++運算符在mtmMap另一種方法:

void insert(const Pair pair){ 
for(begin();iterator->next->data;this++){ 
} 

,但我得到這些錯誤:

「作爲增量操作數需要左值」

「只讀位置增量」

+0

請修復壓痕並平衡大括號。另外,請說明你正在嘗試做什麼。在C++中,「迭代器」指的是一種數據類型,但您顯然在容器類中創建了一個名爲'iterator'的成員變量。 – Potatoswatter

+0

在STL團隊建立更好的方法之前,將迭代狀態「融入」迭代的集合中的這種事情是相當普遍的STL之前(即早期雜湊)。看看標準庫的靈感。 – molbdnilo

+0

另外''data = &pair;''會給你一個無效指針,因爲'pair'是一個函數參數。而且這也是內存泄漏。 – molbdnilo

回答

0

使運算符成爲迭代器的成員函數。順便說一句,也請更喜歡更現代的成語。

template <typename KeyType, typename ValueType, 
      typename CompareFunction = std::less<KeyType> > 
class MtmMap { 
    public: 
     class Node { 
      public: 
       const Pair* data; 
       // the nodes are managed by the linked list, 
       // so use a unique_ptr<> here. 
       unique_ptr<Node> next; 
       // you'll probably want to avoid this. Why should you 
       // have an empty node in your list? 
       Node() : data{nullptr}, next{nullptr} {}; 
       // instead have this: 
       Node(const Pair* d) : data{d}, next{nullptr} {}; 

       // don't do this. 
       // When you use raw pointers, you don't want to own the objects. 
       // in case your linked list has to own the objects, 
       // use unique_ptr<> instead. 
       // if you do, always prefer initializer lists, when possible. 
       /* Node(const Pair pair) { 
        data=new Pair(pair); 
        data=&pair; 
        next=NULL; 
       } */ 
     }; 
    private: 
     // the start node will be managed by the list. 
     // When it is released, all the nodes are released automatically. 
     // But not the data, they point to. 
     unique_ptr<Node> startNode = nullptr; 
    public: 
     class iterator { 
      private: 
       Node* current; 
      public: 
       iterator(Node* c) current{c} {}; 

       bool operator == (const Node& other) { 
        return current == other.current; 
       } 
       Pair& operator*() { 
        return *(current->data); 
       } 
       // ... some other operators. For more details, see: 
       // http://en.cppreference.com/w/cpp/iterator 
       iterator& operator ++() { 
        current = (current == nullptr) ? nullptr : current->next.get(); 
        return *this; 
       } 
     }; 

     iterator begin() { return { startNode }; } 
     iterator end() { return { nullptr }; } 

     // ... 
}; 

// now you can to this: 
MtmMap m; 
// ... populate the map 
for(auto& currentPair: m) { 
    // do whatever you need with currentPair. 
} 

請注意,我還沒有測試此代碼。它可能包含錯誤,只是爲了向你展示這個概念。我使用了一些C++ 11特定的語法。對於大多數編譯器,您仍然必須激活C++ 11支持。

我認爲,這是一項家庭作業。在生產代碼中寫下類似內容之前,請停下來思考,如果std::mapstd::list真的不適合你。他們從很多頭痛中拯救你。

0

看來你在MtmMap上實現了operator++,而不是在迭代器上。你的設計是錯誤的(使用成員迭代器變量???)。你想能夠做到這一點:

for(auto it = begin(); it != end(); it++) // idiomatic 

所以實現你的迭代器類的基礎上。

就這麼你知道,this不是一個對象,它是一個指針。你必須解除引用 - (*this)++。這可能會讓您的代碼按原樣運行。