2011-07-04 40 views
60

我想將給定類的對象映射到另一個類的對象。然而,我想用作關鍵詞的課程不是我自己寫的,只是帶有一些值的簡單的struct。 std :: map命令它的內容,我想知道它是如何實現的,以及是否有任意的類可以用作鍵,或者是否有需要定義的一組需求(運算符和哪些不需要)。什麼要求必須std :: map key類符合成爲有效密鑰?

如果是這樣,我可以爲實現操作符映射用途的類創建一個包裝器。我只需要知道我需要首先實施什麼,並且沒有I found online類的參考指定它們。

回答

54

所有這一切需要的關鍵的是,它是可複製的,可轉讓的。 映射中的排序由 模板的第三個參數(以及構造函數的參數(如果使用))定義。這 默認std::less<KeyType>,它默認爲<運營商, 但沒有要求使用默認值。只要寫一個比較 操作符(最好爲功能對象):

struct CmpMyType 
{ 
    bool operator()(MyType const& lhs, MyType const& rhs) const 
    { 
     // ... 
    } 
}; 

注意,它必須定義一個嚴格的排序,也就是說,如果CmpMyType()(a, b )返回true,那麼CmpMyType()(b, a)必須返回false,如果 都返回假的,元素被認爲是相等的(相同等同類的成員)。

+0

+1確實,它是可複製和可分配的,這是真正的要求。 – juanchopanza

2

set相同:班級必須嚴格按照「小於」的精神排序。要麼重載適當的operator<,要麼提供自定義謂詞。任何兩個對象ab其中!(a<b) && !(b>a)將被視爲相等。

映射容器實際上將按照該排序提供的順序保留所有元素,這就是您如何通過鍵值實現O(log n)查找和插入時間的方式。

3

答案實際上是在你參考的鏈接下,在「比較」模板參數的描述下。

唯一的要求是Compare(默認爲less<Key>,默認使用operator<來比較鍵)必須是「嚴格弱排序」。

18

您需要定義操作<,例如像這樣:

struct A 
{ 
    int a; 
    std::string b; 
}; 

// Simple but wrong as it does not provide the strict weak ordering.  
// As A(5,"a") and A(5,"b") would be considered equal using this function. 
bool operator<(const A& l, const A& r) 
{ 
    return (l.a < r.a) && (l.b < r.b); 
} 

// Better brute force. 
bool operator<(const A& l, const A& r) 
{ 
    if (l.a < r.a) return true; 
    if (l.a > r.a) return false; 

    // Otherwise a are equal 
    if (l.b < r.b) return true; 
    if (l.b > r.b) return false; 

    // Otherwise both are equal 
    return false; 
} 

// This can often be seen written as 
bool operator<(const A& l, const A& r) 
{ 
    // This is fine for a small number of members. 
    // But I prefer the brute force approach when you start to get lots of members. 
    return (l.a < r.a) || 
      ((l.a == r.a) && (l.b < r.b)); 
} 
+0

這是一個可怕的比較運算符。 –

+1

這不僅是可怕的,它是錯的。它沒有提供地圖容器所要求的「嚴格的弱排序」。以上提供了一個蠻力版本來彌補。比較A(5,「A」)和A(5,「B」)之間的區別 –

+0

對,我想發佈一個簡單的例子,並把它搞砸了。感謝Martin修復這個例子。 –

相關問題