为什么我需要包含<compare>标头才能编译 <=>?

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

本文关键字:gt lt 编译 compare 包含 为什么      更新时间:2023-10-16

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

但我对动机感到困惑:

我在默认<=>中看不到任何"库":它可能会返回某种技术上在std中定义的类型,但从某种意义上说,它是一个"假库"类型,编译器必须知道它,因为它必须能够默认operator <=>返回类型auto(更不用说好的编译器中的错误消息指定了<compare>所以很明显有一种语言<=>库链接在这里(。

所以我知道有一些库功能可能需要我包含<compare>但我不明白为什么默认<=>需要我包含该标头,因为编译器无论如何都必须了解制作<=>所需的一切。

注意:我知道大多数时候其他一些标准标题会包含<compare>,这是一个关于语言/库设计的问题,而不是关于C++迫使我无缘无故地编写的额外行。

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

好吧,<=>返回非常真实的类型,这些类型实际上是在<compare>中定义并在那里实现的。就像使用初始值设定项列表来构造一个std::initializer_list<T>一样,它在很大程度上是一个实际在<initializer_list>中定义的真实类型。typeinfo<typeinfo>.

而这些比较类型——std::strong_orderingstd::weak_orderingstd::partial_ordering(最初也是std::strong_equalitystd::weak_equality(——本身就定义了重要的转换语义和其他操作,我们可能希望在未来进行更改。它们确实是非常特殊的语言类型,其中可转换性只朝着一个方向发展,但以一种与继承非常不同的方式(总排序类型只有三个值,但部分排序类型只有四个值......将它们定义为真正的库类型,然后将它们的交互指定为真正的库代码,这实际上要容易得多。

该编译器必须知道它,因为它必须能够默认operator<=>返回类型auto

有点,但不是真的。编译器知道类型的名称是什么,以及如何为基本类型生成它们的值,但它实际上不需要知道更多的东西。返回类型的规则基本上是根据底层成员<=>返回的类型硬编码的,不需要知道这些实际类型是什么样子的。然后你只是调用了执行...无论什么。

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