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;
}
→ Ссылка