如何强制std::weak_ordering

How to force std::weak_ordering

在尝试新的 Tie-Interceptor 三向比较运算符 <=> 时,我想知道什么是这样的示例

struct Foo {
    /*
       ....
    */
    auto operator<=>(const Foo &rhs) const = default;
};

会导致编译器错误

Foo Bar1;
Foo Bar2;
std::strong_ordering(Bar1 <=> Bar2);

但没有

Foo Bar1;
Foo Bar2;
std::weak_ordering(Bar1 <=> Bar2);

Foo 的例子是什么?换句话说,Foo 怎么会不意味着可替代性呢? 我知道我可以自己编写 returns std::weak_ordering ... less/greater/equivalent 运算符的实现,但是如何强制编译器这样做?

到目前为止,我已经阅读了 等书。

... but how to force the compiler to do so?

当您使用auto 作为默认operator<=> 的return 类型时,编译器将选择所有成员的公共比较类别。所以如果你有这样的东西:

// any type that is weakly ordered
struct Weak {
    bool operator==(Weak const&) const;
    std::weak_ordering operator<=>(Weak const&) const;
};

struct Foo {
    Weak w;
    int i;
    auto operator<=>(Foo const&) const = default;
};

然后在类型 Foo 的两个实例上使用 <=> 会给你一个 weak_ordering,因为这是 Weakint 的常见比较类别.

与给定的方式相同:

struct Bar {
    float f;
    auto operator<=>(Bar const&) const = default;
};

Bar::operator<=> 给你 std::partial_ordering.

没有核心语言类型可以为您提供 std::weak_ordering,但是 一些库类型可能:

// some typical C++17 comparable type
struct Widget {
    bool operator==(Widget const&) const;
    bool operator<(Widget const&) const;
};

struct LotsOfWidgets {
    std::vector<Widget> widgets;
    auto operator<=>(LotsOfWidgets const&) const = default;
};

这里的 <=> returns std::weak_ordering(以避免必须假设你所说的 <== 是什么意思)。


或者您可以自己提供。您没有使用auto:

struct WeakInt {
    int i;
    friend std::weak_ordering operator<=>(WeakInt, WeakInt) = default;
};

weak_ordering是用户的选择,是对类型比较意义的明确表达。没有基本类型是弱排序的(浮点数使用 partial_ordering),大多数以某种方式排序的标准库类型要么反映某些模板参数的排序,要么选择更具体的排序。

所以 weak_ordering 仅当 Foo 的子对象本身使用 weak_ordering.

时才由 = default 发生