我想將給定類的對象映射到另一個類的對象。然而,我想用作關鍵詞的課程不是我自己寫的,只是帶有一些值的簡單的struct
。 std :: map命令它的內容,我想知道它是如何實現的,以及是否有任意的類可以用作鍵,或者是否有需要定義的一組需求(運算符和哪些不需要)。什麼要求必須std :: map key類符合成爲有效密鑰?
如果是這樣,我可以爲實現操作符映射用途的類創建一個包裝器。我只需要知道我需要首先實施什麼,並且沒有I found online類的參考指定它們。
我想將給定類的對象映射到另一個類的對象。然而,我想用作關鍵詞的課程不是我自己寫的,只是帶有一些值的簡單的struct
。 std :: map命令它的內容,我想知道它是如何實現的,以及是否有任意的類可以用作鍵,或者是否有需要定義的一組需求(運算符和哪些不需要)。什麼要求必須std :: map key類符合成爲有效密鑰?
如果是這樣,我可以爲實現操作符映射用途的類創建一個包裝器。我只需要知道我需要首先實施什麼,並且沒有I found online類的參考指定它們。
所有這一切需要的關鍵的是,它是可複製的,可轉讓的。 映射中的排序由 模板的第三個參數(以及構造函數的參數(如果使用))定義。這 默認到std::less<KeyType>
,它默認爲<
運營商, 但沒有要求使用默認值。只要寫一個比較 操作符(最好爲功能對象):
struct CmpMyType
{
bool operator()(MyType const& lhs, MyType const& rhs) const
{
// ...
}
};
注意,它必須定義一個嚴格的排序,也就是說,如果CmpMyType()(a, b )
返回true,那麼CmpMyType()(b, a)
必須返回false,如果 都返回假的,元素被認爲是相等的(相同等同類的成員)。
與set
相同:班級必須嚴格按照「小於」的精神排序。要麼重載適當的operator<
,要麼提供自定義謂詞。任何兩個對象a
和b
其中!(a<b) && !(b>a)
將被視爲相等。
映射容器實際上將按照該排序提供的順序保留所有元素,這就是您如何通過鍵值實現O(log n)查找和插入時間的方式。
答案實際上是在你參考的鏈接下,在「比較」模板參數的描述下。
唯一的要求是Compare
(默認爲less<Key>
,默認使用operator<
來比較鍵)必須是「嚴格弱排序」。
您需要定義操作<,例如像這樣:
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));
}
這是一個可怕的比較運算符。 –
這不僅是可怕的,它是錯的。它沒有提供地圖容器所要求的「嚴格的弱排序」。以上提供了一個蠻力版本來彌補。比較A(5,「A」)和A(5,「B」)之間的區別 –
對,我想發佈一個簡單的例子,並把它搞砸了。感謝Martin修復這個例子。 –
+1確實,它是可複製和可分配的,這是真正的要求。 – juanchopanza