2011-09-27 57 views
0

我有一個類,我已經爲其定義了比較運算符。以下是我的代碼寫STL爲相同的用戶定義類型設置和映射

#include <set> 
#include <map> 
#include <list> 

    template <typename _TyV> 
    class Element { 
    public: 
     Element(_TyV in) : m_Label(in){} 
     ~Element() {} 
     bool operator < (const Element & right) const { 
      return m_Label < right.m_Label; 
     } 
    private: 
     _TyV m_Label; 
    protected: 
    }; 
    typedef Element<int> ElementType; 

    int main (int argc, char **argv) { 
     std::set<ElementType> mySet; 
     for (int i = 0; i < 10; i++) { 
      mySet.insert(ElementType(i)); 
     } 
     std::map<ElementType*, std::list<ElementType*> > myMapList; 
     return 0; 
    } 

我迷惑於如何我std::map會工作,因爲我感興趣的std::map元素是指向ElementType。我真正想要的是存儲在std::set實際數據,並在std::map

主要混淆使用指針,以這些元素是圍繞less than operator

回答

7

你的地圖,std::map<ElementType*, std::list<ElementType*> >的關鍵類型作爲其比較器使用std::less,爲正常。

std::less指針類型被定義爲產生一致的排序,但排序是基於地址只有,而不是它可能指向的任何東西。

因此,您的設置根據Element中的operator<對其內容進行排序,但映射會根據鍵的實際指針值對它們進行排序。這可能不是你想要的:(1)它使不同的Element<int>值包含相同的m_Label值作爲映射中的不同鍵,並且(2)這意味着映射將以與集不同的順序。但std::map可以帶一個額外的模板參數來提供一個比較器,所以你可以改變它。

你可以編寫一個比較器,它需要兩個指針,並比較它們指向的對象。當然,假設一旦你使用指針作爲地圖中的一個鍵,你確定它指向的對象將被粘住(在set,我假設,但是如果沒有,那麼在這裏插入樣板講座shared_ptr)。由於Element<int>是便宜的複製,所以使用ElementType作爲密鑰而不是ElementType*幾乎肯定會更好。但是如果int僅僅代表您將來使用的複製代價很高的內容,那麼請更改map比較器。

您可能不在意map中元素的順序。如果你不這樣做,並且如果在map中查找的唯一東西是指向set中的對象的指針,那麼使用ElementType*作爲映射關鍵字而不指定比較器應該沒問題。

+0

ElmentType在這個例子中很便宜,但我希望我的庫能夠處理重和大的對象,並試圖找出避免不必要的副本的選項。根據你的解釋,你認爲我也可以有迭代器的std :: map。即關鍵的地圖將在迭代器std :: set – Avinash

+1

@Avinash:不,''set :: iterator'不是一個隨機訪問迭代器,所以它沒有'operator <'(或者一個'std :: less'專業化)。 –

+0

即使使用自定義比較器,這也行不通? – Avinash