[英]std::map with non-unique key ordering but unique comparison
考慮以下代碼:
#include <iostream>
#include <map>
#include <utility>
struct Key{
int attr1, attr2;
Key(int attr1, int attr2) : attr1(attr1), attr2(attr2) {}
friend bool operator== (const Key& s1, const Key& s2);
friend bool operator< (const Key& s1, const Key& s2);
};
bool operator== (const Key& s1, const Key& s2){
return ((s1.attr1 == s2.attr1) && (s1.attr2 == s2.attr2));
}
bool operator< (const Key& s1, const Key& s2){
return (s1.attr1 < s2.attr1);
}
int main(void){
std::map<Key, int> mmap;
mmap.insert(std::make_pair(Key(10, 10), 5));
mmap.insert(std::make_pair(Key(10, 20), 5));
std::cout << mmap.size() << std::endl;
}
輸出是1
,我希望它是2
。 這似乎是由於在operator<
只比較了attr1
。 但是,如果我是對的,比較不一定是強排序,而是弱排序就足夠了。 這里是否還有其他錯誤,或者我是否必須為其定義一個operator<
Key1 !< Key2 && Key2 !< Key1
意味着Key1 == Key2
成立嗎?
std::map
在比較元素時根本不使用operartor ==
。 默認情況下,在這種情況下,它使用std::less
,它使用您的operator <
。 由於您的operator <
僅比較attr1
,並且兩個對象具有相同的attr1
,因此它們被認為是等效的,因此您在地圖中只有一個對象。
要解決此問題,您需要檢查兩個成員,並且可以使用std::tie
技巧制作一個為您執行此操作的元組
bool operator< (const Key& s1, const Key& s2){
return std::tie(s1.attr1, s1.attr2) < std::tie(s2.attr1, s2.attr2);
}
另一種選擇是使用std::unordered_map
,它使用散列算法和相等運算符。 使用它,您只能對attr1
進行哈希處理,但讓相等運算符檢查attr1
和attr2
以確保不會添加真正的重復項。
如果我是對的,比較不一定是強排序,而是弱排序就足夠了。
你是對的。
輸出是 1,我希望它是 2。
您會錯誤地期望,因為根據您提供的弱排序關系,這些鍵被認為是相等的。
這里還有其他錯誤嗎
不。
我是否必須定義一個
operator<
Key1 !< Key2 && Key2 !< Key1 implies that Key1 == Key2
成立嗎?
如果您希望操作產生一個排序,其中鍵被認為是相等的,當且僅當Key1 == Key2
然后是時,您確實需要定義這樣的運算符。
或者您可以使用可能包含非唯一鍵的多映射。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.