【问题标题】:Full-range comparison operator in C++?C ++中的全范围比较运算符?
【发布时间】:2013-11-24 22:36:55
【问题描述】:

在 C++ 中,可以在类 Foo 上定义 bool operator<(),而像 next_permutation() 这样的 stdlib 算法使用它来推断排序。

但是,仅提供一种方法来检查 Foo 的一个实例是否小于另一个实例,并不能提供所有可能的比较。例如,实例可能相等。

是否有支持 C++ 中全方位比较的标准或协议?

这个问题是由 Ruby 中定义的 <=> "spaceship" 运算符引发的,如果接收者分别小于、等于或大于参数,则该方法返回 -1、0 或 1。

【问题讨论】:

标签: c++


【解决方案1】:

P0515 添加了这个(拼写很奇怪,<=>)。它应该在 C++2x 中

【讨论】:

    【解决方案2】:

    所有使用小于比较器的 C++ 标准函数(和类)都不关心对象是否相等。相反,他们使用“等价”概念定义xy 当且仅当!(x < y) && !(y < x) 是等价的。如果x < y是严格弱序,那么!(x < y) && !(y < x)是等价关系。

    所以不,没有精确的 Ruby 宇宙飞船等价物,因为这些 C++ 操作不接受小于、等于或大于的三分法。但是,您可以很容易地编写:

    template <typename T>
    int spaceship(const T &lhs, const T &rhs) {
        if (lhs < rhs) return -1;
        if (rhs < lhs) return 1;
        return 0;
    }
    

    【讨论】:

    • 谢谢!我很好奇:这个定义没有效率问题吗?这意味着,如果您必须检查等效性,则必须致电operator&lt; 两次!鉴于operator&lt; 是一个任意定义的函数,这里的成本是任意的并且可以累加,例如在热循环中。
    • @DunPeal:通常没有效率问题,因为&lt; 比较(平均而言)比一开始的宇宙飞船比较便宜,所以如果你再做几个也没关系.毫无疑问,有些算法以一种或另一种方式运行得更快。因此,例如,有两种方法可以进行快速排序——2 路分区或 3 路分区。使用&lt;,3路分区必须对每个元素进行最多2次比较,因此对于&lt;=&gt;可以实现比两个完整&lt;比较便宜的类型(例如string),您将从中受益.
    • @DunPeal:如果给定类型支持它,您可以使用模板专业化来优化它,例如std::string 通过std::string::compare 成员函数实现。
    • ... 另一方面,使用二进制搜索,即使&lt;=&gt; 可用,我认为对于大多数类型来说,始终使用&lt; 可能更有效,然后在最后,而不是 &lt;=&gt; 可能会在每次通话时做额外的工作,以便为您提供比您需要的更多信息。不过,我相信以这种方式定义事物的原因不是为了提高效率,而是为了简化界面。你定义一个比较器函数,或者一个运算符重载,你就完成了。然后由算法来尽可能有效地使用它。
    • @SteveJessop:如果没有定义operator==,C++ stdlib(比如说,你提到的快速排序算法)如何知道执行两个小于操作,但如果是直接==?根据我对 C++ 的了解,调用不存在的方法只是一个错误,所以天真地,如果一个对象只定义了 operator&lt;,我希望 == 调用它会失败。
    猜你喜欢
    • 2020-03-28
    • 1970-01-01
    • 2023-03-03
    • 2011-01-21
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    相关资源
    最近更新 更多