6

spaceship 运算符的定义意味着对排序有严格的定义,但这是否会影响您的客户端代码的编写方式,或者只是如何定义您的类比较运算符?

由于在其他帖子中缺少真实世界的示例,我并没有完全理解这部分。

关于宇宙飞船操作员的其他 SO 帖子:

4

2 回答 2

5

你只是比较你一直做的方式:

a < b

只是在幕后,该表达式的候选函数之一也会找到(a <=> b) < 0,如果该候选函数存在并且恰好是最佳可行候选函数,则调用它。

您通常不会<=>直接在“客户端代码”中使用,您只需直接使用您想要的比较。

例如,给定:

struct X {
    int i;

    // this can be = default, just writing it out for clarity
    strong_ordering operator<=>(X const& rhs) const { return i <=> rhs.i; }
};

表达方式

X{42} < X{57};

将评估为X{42} <=> X{57} < 0(没有<候选人,所以<=>非反转是最好的候选人)。X{42} <=> X{57}评估为42 <=> 57which is strong_ordering::less。并且< 0返回true。因此,最初的表达式是true... 正如预期的那样。

同一个运算符也直接给我们 that X{57} > X{42}, thatX{3} >= X{2}等。


的优点<=>是您只需要编写一个运算符而不是四个运算符,该运算符通常比 更容易编写<,您可以正确表达部分订单和全订单之间的区别,并且堆叠它通常更高效(例如,在像string)。

此外,我们不必生活在这个奇怪的世界里,每个人都假装这operator<是唯一存在的关系运算符。

于 2019-01-23T13:35:30.623 回答
4

<=>允许惰性方式也成为高性能方式。您无需更改客户端代码。

当有using std::rel_ops(或boost::ordered等)时,客户可能会看到性能优势。

一个例子

// old and busted
struct Person : boost::totally_ordered<Person>
{
    std::string firstname;
    std::string lastname
    bool operator<(const Person & other) 
    { 
        return std::tie(firstname, lastname)
             < std::tie(other.firstname, other.lastname); 
    }
}

// new hotness
struct Person
{
    std::string firstname;
    std::string lastname;
    auto operator<=>(const Person &) = default;
}

int main()
{
    Person person1 { "John", "Smith" };
    Person person2 { "John", "Smith" };
    std::cout << person2 <= person1 << std::endl;
}
于 2019-01-23T12:05:15.577 回答