Карта C ++ с пользовательским ключом - PullRequest
2 голосов
/ 23 марта 2020

У меня есть пользовательский ключ для карты c ++ с перегруженной '<'. </p>

class CustomKey;

typedef map<CustomKey, int>     KeyValueMap;

class CustomKey {
    public:
    string      key1;
    int         key2;
    int         key3;

    bool operator < (const CustomKey & rhs) const {
        return ((key1 < rhs.key1)
             || ((key1 == rhs.key1) && (key2 < rhs.key2))
             || ((key2 == rhs.key2) && (key3 < rhs.key3)));
    }

    void display() const {
        cout << key1 << ":" << key2 <<":" << key3;
    }
};

Я могу добавить и отобразить все пять приведенных ниже ключей.

void addDataToMap(KeyValueMap & valueMap)   {
    CustomKey   key1 = {"one", 100, 50};
    valueMap[key1] = 1;

    CustomKey   key2 = {"two", 200, 150};
    valueMap[key2] = 2;

    CustomKey   key3 = {"moreabc", 100, 100};
    valueMap[key3] = 27;

    CustomKey   key4 = {"less", 100, 150};
    valueMap[key4] = 30;

    CustomKey   key5 = {"morexyz", 100, 101};
    valueMap[key5] = 33;
}

void displayMap(const KeyValueMap & valueMap)   {
    KeyValueMap::const_iterator iter = valueMap.begin();
    while(iter != valueMap.end())   {
        iter->first.display();
        cout << " => " << iter->second << endl;
        iter++;
    }
}

Но странный поиск не удается для нижнего случая. Различная комбинация сложения в addDataToMap дает разные результаты.

void searchMap(const KeyValueMap & valueMap)    {
    CustomKey   key3 = {"morexyz", 100, 101};
    cout << "MapSize = " << valueMap.size() << endl;
    KeyValueMap::const_iterator iter = valueMap.find(key3);
    if(iter == valueMap.end())  {
        cout << "NotFound" << endl;
        return;
    }

    cout << iter->second << endl;
}

int main()  {
    KeyValueMap     valueMap;

    addDataToMap(valueMap);

    displayMap(valueMap);

    searchMap(valueMap);

    cout << endl;
    return 0;
}

Вывод: -

one:100:50 => 1
moreabc:100:100 => 27
morexyz:100:101 => 33
less:100:150 => 30
two:200:150 => 2
MapSize = 5
NotFound

С '<' logi c, оставшимся тем же, я полагал, все, что добавляется в карта будет найдена. </p>

Ответы [ 2 ]

3 голосов
/ 23 марта 2020

Используйте оператор <определено как </p>

#include <tuple>

//...

bool operator < (const CustomKey & rhs) const {
    return std::tie( key1, key2, key3 ) < std::tie( rhs.key1, rhs.key2, rhs.key3 );
}

Такое определение оператора является ясным и не подвержено ошибкам.

В противном случае ваш оператор не удовлетворяет требованию предоставить строгое слабое отношение порядка.

1 голос
/ 23 марта 2020

Попробуйте рассмотреть случай, когда key1 > rhs.key1 и key2 == rhs.key2 и key3 < rhs.key3, operator < вернут true, что не ожидается.

Вы можете оставить (key1 == rhs.key1) в последнем Бранд operator || в operator <. например,

bool operator < (const CustomKey & rhs) const {
    return ((key1 < rhs.key1) || 
            ((key1 == rhs.key1) && (key2 < rhs.key2)) || 
            ((key1 == rhs.key1) && (key2 == rhs.key2) && (key3 < rhs.key3)));
}

LIVE

...