繁体   English   中英

为什么 C++20 中的空结构没有隐式宇宙飞船运算符?

[英]Why do empty structs in C++20 do not have implicit spaceship operator?

动机:有时我使用 std::variant 来实现“花式”枚举,其中一些枚举状态可以携带 state。

现在,如果我想将<=>用于我的变体,它要求我的空结构已定义 <=>。 这对我来说似乎有点奇怪,因为如果类型有 0 位 state 则该类型的所有实例都是相同的。

完整示例

#include <compare>
#include <iostream>
#include <variant>

struct Off{
    // without this the code does not compile
    auto operator<=>(const Off& other) const = default;
};

struct Running{
    int rpm=1000;
    auto operator<=>(const Running& other) const = default;
};

using EngineState = std::variant<Off, Running>;

int main()
{
    EngineState es1, es2;
    es1<=>es2;
}

默认的比较运算符是选择加入,而不是选择退出。

如果它是选择退出的,那么它可以将无法编译的代码转换为具有某种未知含义的编译代码。 标准委员会试图尽可能地保持向后兼容性。

其原因最终归结为:“可比较”类型意味着什么?

可比较的类型首先是带有的类型。 这种类型的对象带有一个在某种意义上有意义的值。

你的例子就是这样一种情况。 本质上,您正在使用variantOff来使用替代值来增加Running的值状态。 我自己会使用optional<Running> ,但无论如何。 Off是一种在您的问题空间中合法具有价值的类型。 它的价值是“不运行”。

大多数空的 object 类型并非如此。 根据该术语的任何定义, std::in_place_t没有有意义的“价值”。 它是一个标签,用于将就地构造调用分派给某些类型的构造函数。 要求将一个实例与另一个实例进行比较是没有意义的。

但是,您希望在默认情况下使其具有可比性。

很多无状态类型没有以面向值的方式使用。 用于分派到重载集的标签、用于提供对全局资源的基于对象的访问的类型等。这并不是说没有面向值的空类型。 但是它们太多了,单方面宣布它们都应该默认具有可比性似乎很奇怪。

此外,以价值为导向是可比性的必要条件,但它并不是充分的。 对于明显以价值为导向的类型,我们没有默认的可比性。

聚合类型具有所有公共成员,因此没有什么能阻止任何人随时在其中插入任何值。 他们显然是以价值为导向的。

然而聚合类型在默认情况下是不可比较的。 他们也不应该。 并非所有可以假设比较的东西都应该进行比较。

即使可以对特定的值集合进行排序,允许对它们进行排序是否有意义? 这取决于收藏。 如果我有 2D 点类型,可以订购。 应该吗? 我可以理解平等测试,但全面的可比性? 你可以定义它,但这样的比较有意义吗?

这是只有类型的创建者才能回答的问题。 因此,我们强迫类型的创建者询问他们想要什么。

没有成员只是有一些公共成员的特例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM