Почему я должен реализовать operator <при использовании operator () для сортировки std :: set - PullRequest
0 голосов
/ 10 января 2019

Во время проверки кода мой коллега сортировал std :: set с помощью структуры. Я все еще новичок в C ++ и должен был реализовать это сам, чтобы полностью понять это. К сожалению, у меня была некоторая борьба, потому что MSVC заставил меня реализовать operator <после того, как я реализовал operator () структуры. </p>

Может кто-нибудь объяснить мне, почему необходимо реализовать оба оператора, если я использую структуру для сортировки std :: set? Я догадался, что оператор <не нужен, потому что std :: set вызывает некоторую базовую функцию сравнения? </p>

class Hallo {
int one;
int two;
public:
Hallo(int one, int two);

bool operator < (const Hallo& rhs) const
{
    return one < rhs.GetOne();
}

struct cmpStruct{
bool operator()(Hallo const &lhs, Hallo const &rhs) const
{
        return lhs.GetOne() < rhs.GetOne();
}

int main(int ac, char* av[]){
const Hallo a{ 1, 1 };
const Hallo b{ 2, 2 };
const Hallo c{ 3, 3 };
const Hallo d{ 5, 5 };

std::set<Hallo, Hallo::cmpStruct> sortedList{};
std::set<Hallo> unsortedList{};

sortedList.insert(b);
sortedList.insert(c);
sortedList.insert(a);
sortedList.insert(d);

unsortedList.insert(b);
unsortedList.insert(c);
unsortedList.insert(a);
unsortedList.insert(d);

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Может кто-нибудь объяснить мне, почему необходимо реализовать оба оператора, если я использую структуру для сортировки std :: set?

Поскольку вы создали 2 экземпляра std::set с class Hallo в качестве ключа и в первом вы явно использовали cmpStruct в качестве функтора, но во втором вы неявно используете std::less, как указано в документации

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

и std::less использует "некоторую базовую функцию сравнения", которая является operator< документация :

Объект функции для выполнения сравнений. Если не указано иное, вызывает оператор <</strong> для типа T.

Акцент мой. Так что, если вы не специализируете std::less для class Hallo или не замените std::less в std::set экземпляре чем-то другим, для operator< потребуется либо метод, либо отдельная функция.

0 голосов
/ 10 января 2019

Члены любого математического набора являются уникальными; никто не может иметь один и тот же ключ. Но что означает то же самое для определенного пользователем типа, такого как struct? Мы знаем, что означает, что две строки равны или два целых числа. Но значение «то же самое» для вашей структуры зависит от вас и от вас, чтобы определить.

Члены std::set являются уникальными и отсортированными по определению. Таким образом, помимо обеспечения уникальности, std::set представляет членов по порядку. Какой заказ? Опять же, для пользовательских типов, пользователь должен определить, что означает, что один объект «меньше» другого.

Вот тут и приходит operator<. Вы определяете, что значит для одного из ваших объектов быть меньше другого. std::set вызывает ваш пользовательский оператор для вашего пользовательского типа и помещает членов в определенном порядке. Он также использует эту функцию для обеспечения уникальности: если новый элемент не может быть вставлен перед существующим или после него, он равен ему, и вставка отклоняется.

0 голосов
/ 10 января 2019

По умолчанию std::set использует operator < для сравнения двух Hallo экземпляров. Вот почему вам нужно определить функцию operator< для их сравнения. Нет операции по умолчанию для сравнения struct с.

Редактировать 1: указание функции упорядочения или сравнения
Один из конструкторов std::set позволяет указать функцию для сравнения экземпляров Hallo. Если вы не хотите добавлять перегруженный метод operator< в свою структуру, вам нужно передать функцию, которая сравнивает два экземпляра Hallo, в конструктор std::set. Опять же, нет никаких операторов сравнения по умолчанию для экземпляров struct или class; вам придется что-то создать.

Редактировать 2: Назначение функции сравнения
Аргумент функции сравнения std::set позволяет указать функцию сравнения для структуры Hallo. Он позволяет вам создать один набор, который упорядочивает элемент one, и вы можете создать другой набор, который упорядочивает элемент two.

Кроме того, вы можете определить функцию упорядочения по возрастанию или убыванию. Выбор есть.

...