Sobes.tech
Middle+

Ի՞նչ պետք է անել, որպեսզի ձեր դասը օգտագործեք որպես բանալի map կամ unordered_map-ում:

sobes.tech AI

Պատասխան AI-ից

Իմաստության համար std::map:

Անհրաժեշտ է սահմանել համեմատության օպերատոր < ձեր դասի համար:

#include <map>
#include <string>

struct MyKey {
    int id;
    std::string name;

    // Սահմանում ենք `<` օպերատորը
    bool operator<(const MyKey& other) const {
        if (id != other.id) {
            return id < other.id;
        }
        return name < other.name;
    }
};

int main() {
    std::map<MyKey, int> myMap;
    MyKey key1{1, "apple"};
    MyKey key2{2, "banana"};
    myMap[key1] = 10;
    myMap[key2] = 20;
    return 0;
}

Իմաստության համար std::unordered_map:

Անհրաժեշտ է սահմանել հեշ ֆունկցիան (hasher) ձեր դասի համար և, եթե անհրաժեշտ է, հավասարության օպերատոր ==. Ստանդարտ std::hash-ը չի կարող հեշավորել օգտագործողի տիպերը:

Հաշվարկի եղանակներ:

  1. std::hash-ի վերագրում std անվանման տարածքում (չի խորհուրդ տրվում):

    #include <unordered_map>
    #include <string>
    #include <functional>
    
    struct MyKey {
        int id;
        std::string name;
    
        // Սահմանում ենք `==` օպերատորը
        bool operator==(const MyKey& other) const {
            return id == other.id && name == other.name;
        }
    };
    
    // `std::hash`-ի մասնագիտացում MyKey-ի համար
    namespace std {
        template <>
        struct hash<MyKey> {
            size_t operator()(const MyKey& key) const {
                // պարզ օրինակ՝ համակցված հեշներ
                // ավելի բարդ և կայուն հեշ ֆունկցիաներ կարող են նախընտրելի լինել
                return hash<int>()(key.id) ^ (hash<std::string>()(key.name) << 1);
            }
        };
    }
    
    int main() {
        std::unordered_map<MyKey, int> myUnorderedMap;
        MyKey key1{1, "apple"};
        MyKey key2{2, "banana"};
        myUnorderedMap[key1] = 10;
        myUnorderedMap[key2] = 20;
        return 0;
    }
    
  2. Հեշեր փոխանցել որպես տիպային պարամետր:

    #include <unordered_map>
    #include <string>
    #include <functional>
    
    struct MyKey {
        int id;
        std::string name;
    
        // Սահմանում ենք `==` օպերատորը
        bool operator==(const MyKey& other) const {
            return id == other.id && name == other.name;
        }
    };
    
    // Հեշեր կառուցվածքի սահմանում
    struct MyKeyHash {
        size_t operator()(const MyKey& key) const {
            return std::hash<int>()(key.id) ^ (std::hash<std::string>()(key.name) << 1);
        }
    };
    
    int main() {
        // Հաշվարկում ենք MyKeyHash որպես երրորդ տիպային պարամետր
        std::unordered_map<MyKey, int, MyKeyHash> myUnorderedMap;
        MyKey key1{1, "apple"};
        MyKey key2{2, "banana"};
        myUnorderedMap[key1] = 10;
        myUnorderedMap[key2] = 20;
        return 0;
    }
    

Երկու դեպքում էլ std::unordered_map-ի համար անհրաժեշտ է նաև == հավասարության օպերատորը։