Сравнение std::minmax с парой

Стандартные алгоритмы min а также max можно сравнить с одним значением. Тем не менее minmax Возвращаемое значение алгоритма нельзя сравнить с парой значений:

#include <algorithm>
#include <utility>

template<class T1, class T2>
constexpr auto make_cref_pair(T1&& t1, T2&& t2)
{
    return std::pair<T1 const&, T2 const&>(std::forward<T1>(t1), std::forward<T2>(t2));
}

int main()
{
    static_assert(std::min(2, 1) == 1); // OK
    static_assert(std::max(2, 1) == 2); // OK
    //static_assert(std::minmax(2, 1) == std::make_pair(1, 2)); // ERROR, const int& vs int pair comparison
    static_assert(std::minmax(2, 1) == std::pair<const int&, const int&>(1, 2)); // OK
    static_assert(std::minmax(2, 1) == make_cref_pair(1, 2)); // OK
}

Живой пример

Причина в том, что make_pair(2, 1) возвращает pair<int, int> а также minmax(1, 2) возвращает pair<const int&, const int&>, Там нет ссылки-смешивания operator== перегрузки для pair,

Исправление заключается в явном написании std::pair<const int&, const int&>(int, int) или обернуть это в домашнем make_cref_pair функция.

Вопросы: есть ли более чистый способ сравнить minmax возвращаемое значение против pair ценностей? И правильно ли я справился со ссылками в моем make_cref_pair?

3 ответа

Решение

std::minmax имеет initializer_list перегрузки. Это возвращает non-const нереферентная пара:

static_assert(std::minmax({2, 1}) == std::make_pair(1, 2));

К сожалению, это может быть менее производительным, поскольку сложности соответственно "ровно одно сравнение" и "не более (3/2) * t.size() приложения соответствующего предиката ".

Одна вещь, которую вы могли бы сделать, это воспользоваться std::minmax перегрузка, которая занимает std::initializer_list<T> и возвращает std::pair<T,T>, Используя то, что вы могли бы иметь

int main()
{
    const int a = 10, b = 20;
    static_assert(std::minmax({2, 1}) == std::make_pair(1, 2));
    static_assert(std::minmax({a, b}) == std::make_pair(a, b));
}

Который скомпилирует и позволяет избавиться от make_cref_pair, Это называется std::minmax_element поэтому я не уверен, если это снижает эффективность или нет.

Одним из вариантов является явное преобразование левой части в std::pair<int,int>:

#include <algorithm>
#include <utility>

template <typename T1, typename T2>
constexpr std::pair<T1,T2> myminmax(const T1& t1, const T2& t2)
{
    return std::minmax(t1,t2);
}

int main()
{
    static_assert(myminmax(2, 1) == std::make_pair(1, 2));
}
Другие вопросы по тегам