[英]What requirements must std::map key classes meet to be valid keys?
我想將給定 class 的 map 對象轉換為另一個對象。 然而,我想用作鍵的 class 不是我寫的,它是一個帶有幾個值的簡單struct
。 std::map 訂購了它的內容,我想知道它是如何做到的,以及是否可以將任意 class 用作密鑰,或者是否有一組需要定義的要求(操作員和其他)。
如果是這樣,我可以為 class 創建一個包裝器,實現 map 使用的運算符。 我只需要知道我首先需要實現什么,我在網上找到的 class 的參考資料都沒有指定它們。
密鑰所需要的只是它是可復制和可分配的。 map 中的排序由模板的第三個參數(以及構造函數的參數,如果使用)定義。 這默認為std::less<KeyType>
,默認為<
運算符,但不需要使用默認值。 只需編寫一個比較運算符(最好作為函數對象):
struct CmpMyType
{
bool operator()( MyType const& lhs, MyType const& rhs ) const
{
// ...
}
};
請注意,它必須定義嚴格的排序,即如果CmpMyType()( a, b )
返回 true,則CmpMyType()( b, a )
必須返回 false,如果兩者都返回 false,則認為元素相等(相同的等價類)。
您需要定義運算符<,例如這樣:
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 ));
}
答案實際上在您鏈接的參考資料中,在“比較”模板參數的描述下。
唯一的要求是Compare
(默認為less<Key>
,默認使用operator<
來比較鍵)必須是“嚴格的弱排序”。
與set
相同: class 必須本着“小於”的精神進行嚴格的排序。 重載適當的operator<
,或提供自定義謂詞。 !(a<b) && !(b>a)
將被視為相等的任何兩個對象a
和b
。
map 容器實際上將按照該排序提供的順序保留所有元素,這就是您可以通過鍵值實現 O(log n) 查找和插入時間的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.