QMap::contains возвращает не то, что ожидалось
Я пытаюсь написать структуру для хранения телефонных записей. Нужно обеспечить уникальность пары ФИО+номер, поэтому я выбрала QMap, где в качестве ключа используется KeyClass:
class KeyClass
{
private:
QString FirstName;
QString MiddleName;
QString LastName;
QString Number;
public:
KeyClass(QStringList elems);
KeyClass();
friend bool operator< (const KeyClass &k1, const KeyClass &k2);
};
KeyClass::KeyClass(QStringList elems)
{
this->Number = elems[0];
this->FirstName = elems[1];
this->MiddleName = elems[2];
this->LastName = elems[3];
}
KeyClass::KeyClass()
{
this->Number = "";
this->FirstName = "";
this->MiddleName = "";
this->LastName = "";
}
inline bool operator<(const KeyClass&k1, const KeyClass&k2)
{
if (k1.FirstName != k2.FirstName)
return k1.FirstName < k2.FirstName;
if (k1.MiddleName != k2.MiddleName)
return k1.MiddleName < k1.MiddleName;
if (k1.LastName != k2.LastName)
return k1.LastName < k2.LastName;
return k1.Number < k2.Number;
}
Проблема возникает, когда я пытаюсь добавить отличающиеся на одно-два поля значения. К примеру, если уже существует запись с ключом "Иван" "Иванович" "" "номер", то её можно найти по "Иван" "" "Иванов" "номер" и QMap::contains вернет true. Я не понимаю, почему так происходит, хотя полагаю, что могла некорректно перегрузить оператор сравнения.
Ответы (2 шт):
Автор решения: Ekaterina
→ Ссылка
Решила вопрос таким образом:
inline bool operator<(const KeyClass&k1, const KeyClass&k2)
{
if (QString::compare(k1.FirstName, k2.FirstName))
return QString::compare(k1.FirstName, k2.FirstName);
if (QString::compare(k1.MiddleName, k2.MiddleName))
return QString::compare(k1.MiddleName, k2.MiddleName);
if (QString::compare(k1.LastName, k2.LastName))
return QString::compare(k1.LastName, k2.LastName);
return QString::compare(k1.Number, k2.Number);
}
Автор решения: Andrej Levkovitch
→ Ссылка
Небольшой лайфхак по написанию компараторов для составных объектов:
#include <iomanip>
#include <iostream>
#include <string>
#include <tuple>
class Key {
public:
Key(const std::string &alpha, const std::string &bravo,
const std::string &charlie)
: alpha_{alpha}, bravo_{bravo}, charlie_{charlie} {}
bool operator<(const Key &second) {
return std::tie(alpha_, bravo_, charlie_) <
std::tie(second.alpha_, second.bravo_, second.charlie_);
}
private:
std::string alpha_;
std::string bravo_;
std::string charlie_;
};
int main() {
Key first{"Amadeus", "Mocart", "A"};
Key second{"Amadeus", "Mocart", "B"};
bool less = first < second;
bool not_less = second < first;
std::cout << std::boolalpha << less << ' ' << not_less << std::endl;
}