Оператор less than не гарантирует уникальность набора объектов

Я пытаюсь создать набор объектов, называемых гостями. Для этого я перегрузил оператор less than. Проблема в том, что я не получаю уникальные элементы. Я не могу понять, почему. В следующем примере размер набора всегда равен 2.

// Online C++ compiler to run C++ program online
#include <iostream>
#include <set>
#include <string>

class Guest{
    public:
     Guest(const std::string &fn, const std::string &ln, const std::string &em, const std::string &loy):firstname(fn), lastname(ln), email(em),loyalty(loy){}

     std::string firstname;
     std::string lastname;
     std::string email;
     std::string loyalty;
    
};

bool operator<(const Guest& l, const Guest& r){
    return (l.firstname < r.firstname) or ((l.firstname == r.firstname) and
           ((l.lastname < r.lastname) or ((l.lastname == r.lastname) and
           ((l.email < r.email) or ((l.email == r.email) and
           ((l.loyalty < r.loyalty) or ((l.loyalty == r.loyalty))))))));
}

int main() {
    Guest g1("g1","g2","g3","g4");
    Guest g2("g1","g2","g3","g4");
    
    std::set<Guest> guests = {g1,g2};
    std::cout << guests.size() << std::endl; //Size is always 2 in here. It should be 1
    return 0;
}

Ваш operator< на самом деле ведет себя как <=. Или спросите себя, действительно ли вы хотите, чтобы g1 < g1 было правдой или нет. Объект никогда не может быть меньше самого себя.

churill 10.04.2022 14:44

Что ж, если вы на самом деле проработаете свою логику или попробуете сравнить, вы обнаружите, что и g1 < g2 верно, и g2 < g1 также верно. Как сказал бы мистер Спок: это нелогично.

Sam Varshavchik 10.04.2022 14:44

Боже, благослови мистера Спока.

Hani Gotc 10.04.2022 14:48
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
3
27
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны удалить последнюю часть or ((l.loyalty == r.loyalty)), иначе operator< вернет true, когда все элементы данных Guest эквивалентны.

bool operator<(const Guest& l, const Guest& r){
    return (l.firstname < r.firstname) or ((l.firstname == r.firstname) and
           ((l.lastname < r.lastname) or ((l.lastname == r.lastname) and
           ((l.email < r.email) or ((l.email == r.email) and
           ((l.loyalty < r.loyalty) ))))));
}

Или сделать это намного проще с std::tie.

bool operator<(const Guest& l, const Guest& r){
    return std::tie(l.firstname, l.lastname, l.email, l.loyalty) < 
           std::tie(r.firstname, r.lastname, r.email, r.loyalty);
}

Другие вопросы по теме