Путаница относительно операторов сравнения в std :: min, std :: max - PullRequest
0 голосов
/ 15 февраля 2020

std::min и std::max позволяют настраивать компараторы, но я немного запутался в том, как работает порядок.

Рассмотрим следующее:

   int i = 1;
   int j = 2;

   auto min_val = min(i, j, [](const auto val1, const auto val2){
      if(val1 < val2) return true;
      return false;
   });

Возвращает минимальное значение , что составляет i. Но я не понимаю, почему мы используем < вместо > и почему val1 и val2 появляются слева и справа от операнда соответственно.

Рассмотрим следующее:

   int i = 1;
   int j = 2;

   auto max_val = max(i, j, [](const auto val1, const auto val2){
      if(val1 > val2) return true;
      return false;
   });

Я думал, что это вернет максимальное значение, но фактически возвращает минимальное значение, и опять же, мы должны использовать операнд <. Может ли кто-нибудь объяснить, что происходит под капотом?

Я столкнулся с этой проблемой и с некоторыми другими вещами, я думаю, с std::priority_queue и std::map, где операторы упорядочивания и сравнения не очень интуитивны для меня, и в большинстве случаев мне приходится угадай и проверь, чтобы получить то, что я хочу.

1 Ответ

2 голосов
/ 15 февраля 2020

Это в основном сводится к тому, как эти функции определены в стандарте. std::max, например, определяет компаратор (вашу лямбду) следующим образом:

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

Обычно, когда речь идет о порядке значений в стандартной библиотеке c ++, это (почти?) всегда std::less, который используется в качестве компаратора по умолчанию, который выполняет точно left < right.

Относительно того, почему всегда нужно удовлетворять a < b. Я думаю, что это просто уменьшит накладные расходы на кодирование, если вы сами напишите это. Представьте себе такой компаратор, как этот:

struct MyComp
{
    bool operator()(MyType a, MyType b) const
    {
        return a.getValue() < b.getValue();
    }
};

Поскольку все конструкции в стандартной библиотеке требуют, чтобы ваш компаратор возвращал значение true, если a < b, вы можете использовать один простой компаратор для множества конструкций. Например,

auto maxVal = std::max(a, b, MyComp{});
auto minVal = std::min(a, b, MyComp{});
std::map<MyType, MyComp> myMap;

будет работать только с одним компаратором.

...