簡體   English   中英

具有非唯一鍵排序但唯一比較的 std::map

[英]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進行哈希處理,但讓相等運算符檢查attr1attr2以確保不會添加真正的重復項。

如果我是對的,比較不一定是強排序,而是弱排序就足夠了。

你是對的。

輸出是 1,我希望它是 2。

您會錯誤地期望,因為根據您提供的弱排序關系,這些鍵被認為是相等的。

這里還有其他錯誤嗎

不。

我是否必須定義一個operator<

 Key1 !< Key2 && Key2 !< Key1 implies that Key1 == Key2

成立嗎?

如果您希望操作產生一個排序,其中鍵被認為是相等的,當且僅當Key1 == Key2然后是時,您確實需要定義這樣的運算符。

或者您可以使用可能包含非唯一鍵的多映射。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM