将 std::minmax 与一对进行比较
Comparing std::minmax against a pair
标准算法 min
和 max
可以与单个值进行比较。但是,minmax
算法 return 值无法与一对值进行比较:
#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)
return 是 pair<int, int>
和 minmax(1, 2)
return 是 pair<const int&, const int&>
。 pair
没有引用混合 operator==
重载。
修复方法是显式编写 std::pair<const int&, const int&>(int, int)
或将其包装在自制的 make_cref_pair
函数中。
问题:是否有更清晰的方法来比较 minmax
return 值与 pair
值?我是否正确处理了 make_cref_pair
中的引用?
std::minmax
有一个 initializer_list
过载。这 returns 个 non-const
非参考对:
static_assert(std::minmax({2, 1}) == std::make_pair(1, 2));
不幸的是,这可能会降低性能,因为复杂度分别为 "exactly one comparison" 和 "at most (3/2) * t.size()
applications of the corresponding predicate"。
您可以做的一件事是利用 std::minmax
重载,它需要一个 std::initializer_list<T>
和 returns 一个 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));
}
其中 will compile 并允许您摆脱 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));
}
标准算法 min
和 max
可以与单个值进行比较。但是,minmax
算法 return 值无法与一对值进行比较:
#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)
return 是 pair<int, int>
和 minmax(1, 2)
return 是 pair<const int&, const int&>
。 pair
没有引用混合 operator==
重载。
修复方法是显式编写 std::pair<const int&, const int&>(int, int)
或将其包装在自制的 make_cref_pair
函数中。
问题:是否有更清晰的方法来比较 minmax
return 值与 pair
值?我是否正确处理了 make_cref_pair
中的引用?
std::minmax
有一个 initializer_list
过载。这 returns 个 non-const
非参考对:
static_assert(std::minmax({2, 1}) == std::make_pair(1, 2));
不幸的是,这可能会降低性能,因为复杂度分别为 "exactly one comparison" 和 "at most (3/2) * t.size()
applications of the corresponding predicate"。
您可以做的一件事是利用 std::minmax
重载,它需要一个 std::initializer_list<T>
和 returns 一个 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));
}
其中 will compile 并允许您摆脱 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));
}