Стандартная библиотечная функция C++ std::min_element()
принимает объект функции в качестве последнего аргумента, а возвращаемый тип этого объекта — bool
. Почему нет int
?
При истинности или ложности у нас есть только два варианта: <
или >
, но что, если две записи одинаковы, то есть ==
?
В C эта ситуация обрабатывается путем выбора типа возвращаемого значения int
. Но это не делается для std::min_element()
в C++.
Что является причиной этого?
@santoshdhanawade это в стандарте, так что все они
Что бы вы получили от этой информации? Предполагается, что функция возвращает наименьший элемент (отсюда и название min_element
). Ему не нужно заботиться о равенстве, что вы получите от этого в конечном результате? Логического значения достаточно, чтобы определить, меньше ли один элемент другого. То, как вы обрабатываете равенство, зависит от вашей реализации этого вызываемого объекта.
По словам cppreference:
bool cmp(const Type1 &a, const Type2 &b);
comparison function object (i.e. an object that satisfies the requirements of Compare) which returns true if a is less than b.
Я укажу, что это согласуется с другими частями std
, такими как sort
и map
, которые упорядочивают вещи на основе функтора, удовлетворяющего Сравнивать. Тот же вопрос можно распространить на все эти вещи.
What is the reason?
Первоначальный автор и комитет по стандартам считали, что это более естественный способ выражения упорядоченности.
Есть некоторые проблемы с использованием трехстороннего сравнения через int
.
int
имеет более трех значений. Поэтому вам нужно выполнить дальнейшие арифметические действия с возвращаемым значением.struct three_way_compare
{
int operator()(int lhs, int rhs) { return lhs - rhs; }
// Undefined behaviour when rhs is a large positive value and lhs is a large negative value
}
Вы можете синтезировать трехстороннее сравнение, дважды вызвав свой функтор. Справочник определяет требования, используя
equiv(a, b)
, an expression equivalent to!comp(a, b) && !comp(b, a)
Обратите внимание, что для C++20 в язык добавляется трехстороннее сравнение с operator <=>
. Я не уверен, изменяются ли существующие алгоритмы, чтобы использовать их, когда они доступны.
Если в вашем контейнере нет NAN
значений с плавающей запятой, в этом случае сравнения все возвращают false
.
@KhouriGiordano Да, попытка сортировки NAN не определена.
Спасибо за подробное объяснение. Я думаю, мне больше интересно узнать, как реализация алгоритма определяет, имеют ли две записи одинаковые значения на основе истинного/ложного вывода функции сравнения. Предположим, я решил написать реализацию функции сравнения следующим образом: bool compare(int & val1, int & val2) { return (val1 < val2) } Может ли с помощью такой функции сравнения алгоритм узнать, имеют ли две записи одинаковое значение, используя ! comp(a, b) && !comp(b, a) ? Он оценивается как false с приведенной выше функцией сравнения.
@Rushikesh comp
- это любое сравнение, которое вы приводите. В случае <
он рассматривает как эквивалентные любые a
и b
такие, что !(a < b) && !(b < a)
истинно. Это не обязательно то же самое, что и a == b
какой компилятор???