почему библиотечная функция C ++ std :: min_element принимает функтор, который принимает объект функции типа возврата bool, а не int, как в C? - PullRequest
1 голос
/ 30 мая 2019

Функция стандартной библиотеки C ++ std::min_element() принимает объект функции в качестве последнего аргумента, а тип возвращаемого объекта - bool. Почему это не int?

При true или false у нас есть только два варианта: < или >, но что, если две записи одинаковы, т.е. ==?

В C эта ситуация обрабатывается путем выбора типа возвращаемого значения int. Но это не сделано для std::min_element() в C ++.

В чем причина этого?

Ответы [ 2 ]

6 голосов
/ 30 мая 2019

Что бы вы получили от этой информации? Функция должна возвращать наименьший элемент (отсюда и имя min_element). Не нужно заботиться о равенстве, что бы вы получили от этого в конечном результате? Логического значения достаточно, чтобы определить, меньше ли один элемент, чем другой. То, как вы справляетесь с равенством, зависит от вашей реализации этого вызываемого.

В словах cppreference :

bool cmp(const Type1 &a, const Type2 &b);

объект функции сравнения (то есть объект, который удовлетворяет требованиям Compare), который возвращает true, если a меньше, чем b.

3 голосов
/ 30 мая 2019

Я укажу, что это согласуется с другими частями std, такими как sort и map, которые все упорядочивают на основе функтора, который удовлетворяет Сравните . Один и тот же вопрос может быть распространен на все эти вещи.

В чем причина?

Первоначальный автор и комитет по стандартам считали, что это более естественный способ выражения порядка.

Есть некоторые проблемы с использованием трехстороннего сравнения через 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), выражение, эквивалентное !comp(a, b) && !comp(b, a)

Обратите внимание, что для C ++ 20 в язык добавляется трехстороннее сравнение с operator <=>. Я не уверен, изменяются ли существующие алгоритмы, чтобы использовать их, когда они доступны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...