为什么我需要包含 <compare> header 来让 <=> 编译?

Why do I need to include <compare> header to get <=> to compile?

我知道技术答案是:因为标准是这么说的。

但我对动机感到困惑:

我在默认 <=> 中看不到任何东西 "library":它可能 return 在 std 中技术上定义的某种类型,但它是 "fake library" type 在某种意义上编译器必须 know 因为它必须能够默认 operator <=>auto return 类型(更不用说好的编译器中的错误消息指定<compare> 所以很明显这里有一个语言<=>库link)。

所以我知道有一些 library functionality 可能需要我包含 <compare> 但我不明白为什么默认 <=> 需要我包含那个 header 因为无论如何,编译器必须知道制作 <=> 所需的一切。

注意:我知道大多数时候一些其他标准 header 会包含 <compare>,这是一个关于 language/library 设计的问题,与多出一行无关C++ 强迫我无缘无故地写。

it may return some type that is technically defined in std but it is a "fake library" type in a sense

嗯,<=> returns 类型是 very much real,它们实际上是在 <compare> 中定义并在那里实现的。与使用初始值设定项列表构造 std::initializer_list<T> 的方式相同,这是在 <initializer_list> 中实际定义的非常真实的类型。 typeinfo<typeinfo> 中。

那些比较类型 - std::strong_orderingstd::weak_orderingstd::partial_ordering(最初还有 std::strong_equalitystd::weak_equality) - 它们本身有 non-trivial 转换语义和定义在它们上面的其他操作,我们可能希望在未来改变。它们确实是非常特殊的语言类型,其中可转换性仅在一个方向上进行,但在某种程度上与继承非常不同(总排序类型只有三个值,但部分排序类型只有四个值......)。将它们定义为真正的库类型,然后将它们的交互指定为真正的库代码,真的要容易得多。

that compiler must know about it since it must be able to default operator<=> with auto return type

有点,但不是真的。编译器知道类型的名称是什么,以及如何为基本类型生成它们的值,但它实际上不需要知道更多。 return 类型的规则基本上是基于 underyling 成员的 <=>s return 的类型硬编码的,不需要知道这些实际类型是什么样子的。然后你只是调用函数来做......不管怎样。

您必须包含 header 的代价是输入 #include <compare> 然后解析它。编译器必须综合这些类型的成本是必须为每个 TU 支付的成本,无论它是否进行任何 three-way 比较。另外 if/when 我们想更改这些类型,无论如何更改库类型比更改语言类型更容易。