是什么让一些名为 Functions/Operators 的人与众不同?

What makes some named Functions/Operators special?

关于某些 C++20 features 的文档,我在 <compare> header 下遇到了一些命名函数和运算符,如下所示:

  constexpr bool is_eq  (partial_ordering cmp) noexcept { return cmp == 0; }
  constexpr bool is_neq (partial_ordering cmp) noexcept { return cmp != 0; }
  constexpr bool is_lt  (partial_ordering cmp) noexcept { return cmp < 0; }
  constexpr bool is_lteq(partial_ordering cmp) noexcept { return cmp <= 0; }
  constexpr bool is_gt  (partial_ordering cmp) noexcept { return cmp > 0; }
  constexpr bool is_gteq(partial_ordering cmp) noexcept { return cmp >= 0; }

Also<utility> 下:

template< class T, class U >
constexpr bool cmp_greater_equal( T t, U u ) noexcept
{
    return !cmp_less(u, t);
}

template< class T, class U >
constexpr bool cmp_less_equal( T t, U u ) noexcept
{
    return !cmp_greater(t, u);
}

关于自定义比较器(或简单比较器)与这些函数之间的区别,我们应该知道什么?他们有什么特别之处?

第一组函数是 库支持的一部分,已添加到 C++20 中。这些实用程序用于发现自己直接使用 <=> 而不是通过核心语言隐式使用的情况。

一方面,飞船的工作方式是返回一个可以与0进行比较的对象,从而表示两个对象之间的顺序关系。

  • (a <=> b) == 0当且仅当a == b
  • (a <=> b) < 0当且仅当a < b
  • 等等

现在,如果您发现自己直接使用 a <=> b,或处理来自其他来源的结果对象,您可以与 0 进行比较以检查您想要的关系。但是,生成的代码可以说不是最容易阅读的。

所以这些实用程序已添加到库中。它们的存在是为了使代码更具表现力。它们允许我们写 is_eq(a <=> b)is_lt(a <=> b) 来查询三路比较的含义。我认为它传达的意图比与 0 的直接比较要清楚得多。同样,它仅适用于我们可能需要直接处理 <=> 结果的极少数情况。


另一组函数有另一个用途。直接比较整数时,操作数会进行一定的整数提升。所以 -1 < 0u 的结果有点不直观 false。这是因为 -1 在比较之前被提升为无符号整数(因为 0u 是无符号整数文字)。这环绕成一个非常大的无符号数,当然不小于 0。

为了更好地支持混合比较,添加了这些函数。他们检查所涉及的类型,并在给定所涉及的值的情况下给出数学上正确的结果,而不会由于整数提升期间发生的值转换而偏离轨道。与通过 <std::cmp_less(-1, 0u) returns true 的直接比较形成对比。