简体   繁体   English

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

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

Motivation: sometimes I use std::variant to implement "fancy" enum where some enum states can carry state.动机:有时我使用 std::variant 来实现“花式”枚举,其中一些枚举状态可以携带 state。

Now if I want to use the <=> for my variant it requires that my empty structs have defined <=>.现在,如果我想将<=>用于我的变体,它要求我的空结构已定义 <=>。 That seems a bit weird to me since if type has 0 bits of state all instances of that type are same.这对我来说似乎有点奇怪,因为如果类型有 0 位 state 则该类型的所有实例都是相同的。

Full example :完整示例

#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;
}

The defaulted comparison operator is opt-in, not opt-out.默认的比较运算符是选择加入,而不是选择退出。

If it was opt-out, then it could turn code that would not compile into code that compiles with some unknown meaning.如果它是选择退出的,那么它可以将无法编译的代码转换为具有某种未知含义的编译代码。 The standard committee tries to maintain backwards compatibility as much as possible.标准委员会试图尽可能地保持向后兼容性。

The reason for this ultimately comes down to this: what does it mean for a type to be "comparable"?其原因最终归结为:“可比较”类型意味着什么?

A type that is comparable is, first and foremost, a type which carries a value .可比较的类型首先是带有的类型。 Objects of such types carry a value that is meaningful in some sense.这种类型的对象带有一个在某种意义上有意义的值。

Your example is one such case.你的例子就是这样一种情况。 Essentially, you are using variant and Off to augment the value-state of Running with an alternative value.本质上,您正在使用variantOff来使用替代值来增加Running的值状态。 I would have used optional<Running> myself, but whatever.我自己会使用optional<Running> ,但无论如何。 Off is a type which legitimately has a value within your problem space. Off是一种在您的问题空间中合法具有价值的类型。 Its value being "not running".它的价值是“不运行”。

This is not the case for most empty object types.大多数空的 object 类型并非如此。 std::in_place_t has no meaningful "value" by any definition of that term.根据该术语的任何定义, std::in_place_t没有有意义的“价值”。 It's a tag used to dispatch in-place construction calls to constructors of certain types.它是一个标签,用于将就地构造调用分派给某些类型的构造函数。 Asking to compare one instance to another makes no sense.要求将一个实例与另一个实例进行比较是没有意义的。

Yet you want to make it comparable by default.但是,您希望在默认情况下使其具有可比性。

There are a lot of stateless types that are not used in a value-oriented way.很多无状态类型没有以面向值的方式使用。 Tags for dispatching to overload sets, types used to provide object-based access to global resources, etc. That's not to say that there are no value-oriented empty types.用于分派到重载集的标签、用于提供对全局资源的基于对象的访问的类型等。这并不是说没有面向值的空类型。 But there are enough of them that unilaterally declaring that all of them ought to be comparable by default seems very strange.但是它们太多了,单方面宣布它们都应该默认具有可比性似乎很奇怪。

Also, being value-oriented is a necessary condition for comparability, but it is not alone sufficient .此外,以价值为导向是可比性的必要条件,但它并不是充分的。 We don't have default comparability for types that are clearly value-oriented.对于明显以价值为导向的类型,我们没有默认的可比性。

Aggregate types have all public members, so there's nothing stopping anyone from shoving any value in them at any time.聚合类型具有所有公共成员,因此没有什么能阻止任何人随时在其中插入任何值。 They are clearly value-oriented.他们显然是以价值为导向的。

Yet aggregate types are not comparable by default.然而聚合类型在默认情况下是不可比较的。 Nor should they be.他们也不应该。 Not everything which could hypothetically be compared should be compared.并非所有可以假设比较的东西都应该进行比较。

Even if a particular collection of values could be ordered, does it make sense to permit them to be ordered?即使可以对特定的值集合进行排序,允许对它们进行排序是否有意义? That depends on the collection.这取决于收藏。 If I have a 2D point type, it could be ordered.如果我有 2D 点类型,可以订购。 But should it?应该吗? I can understand equality testing, but full-on comparability?我可以理解平等测试,但全面的可比性? You can define it, but is such a comparison ever meaningful ?你可以定义它,但这样的比较有意义吗?

That's a question only the creator of the type can answer.这是只有类型的创建者才能回答的问题。 Therefore, we force the creator of types to ask for what they want.因此,我们强迫类型的创建者询问他们想要什么。

And having no members is just a special case of having some public members.没有成员只是有一些公共成员的特例。

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

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