【问题标题】:Why do I need to include <compare> header to get <=> to compile?为什么我需要包含 <compare> 标头才能使 <=> 编译?
【发布时间】:2020-09-09 20:59:54
【问题描述】:

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

但我对动机感到困惑:

我在默认的&lt;=&gt; 中没有看到任何“库”:它可能会返回某种在技术上定义在std 中的类型,但在某种意义上它是一个“假库”类型,编译器必须know 关于它因为它必须能够默认 operator &lt;=&gt;auto 返回类型(更不用说好的编译器中的错误消息指定 &lt;compare&gt; 所以很明显这里有一个语言库链接)。

所以我知道有一些library functionality 可能需要我包含&lt;compare&gt;,但我不明白为什么默认&lt;=&gt; 需要我包含该标头,因为无论如何编译器都必须知道制作@ 所需的一切987654330@。

注意:我知道大多数时候其他一些标准标题会包含&lt;compare&gt;,这是一个关于语言/库设计的问题,而不是关于 C++ 强迫我在没有充分理由的情况下编写的额外行。

【问题讨论】:

  • 可能与您需要包含 &lt;new&gt; 以使用放置新语法的原因相似。
  • &lt;typeinfo&gt; 相同,只需使用typeid
  • @eerorika 有趣的是,您无需包含 &lt;new&gt; 即可使用默认的非放置 operator new。因此,似乎没有技术上的理由来强制用户包含这些内置操作的标头。
  • "它是“假库”类型" 没有这样的东西。类型要么是编译器定义的基本类型,要么不是。
  • @Brian new 是语言关键字,因此没有标题。但是placement-new可以被用户重载,其中&lt;new&gt;定义了默认的placement-new

标签: c++ c++20 spaceship-operator


【解决方案1】:

它可能会返回某种在技术上在 std 中定义的类型,但在某种意义上它是一种“假库”类型

好吧,&lt;=&gt; 返回的类型是 very much real,实际上是在 &lt;compare&gt; 中定义并在那里实现的。与使用初始化列表构造std::initializer_list&lt;T&gt; 的方式相同,std::initializer_list&lt;T&gt; 是在&lt;initializer_list&gt; 中实际定义的真正类型。和typeinfo&lt;typeinfo&gt;

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

编译器必须知道它,因为它必须能够默认 operator&lt;=&gt;auto 返回类型

有点,但不是真的。编译器知道类型的名称是什么,以及如何为基本类型生成它们的值,但它实际上不需要知道更多。返回类型的规则基本上是基于底层成员&lt;=&gt;s 返回的类型进行硬编码的,不需要知道这些实际类型是什么样的。然后你只是调用函数来做......无论如何。

您必须包含标题的成本是输入#include &lt;compare&gt; 然后解析它。编译器必须综合这些类型的成本是必须为每个 TU 支付的成本,无论它是否进行任何三向比较。另外,如果/当我们想要更改这些类型时,无论如何更改库类型比更改语言类型更容易。

【讨论】:

  • “编译器知道类型的名称是什么,以及如何为基本类型生成它们的值,但实际上它不需要知道更多。” AFAIK 编译器也需要知道选择复合成员的最弱比较类别。
  • @NoSense 我讲过了,不是吗?
  • 我不这么认为,因为编译器需要了解很多关于这些类型的信息,而不仅仅是名称。但这是一个意见问题......而且不值得大量输入。我觉得基本的比较类别永远不会改变,并且可以在语言中进行硬编码。但至少我知道动机,所以我会接受答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
相关资源
最近更新 更多