[英]Why was std::ranges::less introduced?
在std::ranges::less
上的 cppreference 上,在注释中我们可以看到:
与
std::less
不同,std::ranges::less
要求所有六个比较运算符<
、<=
、>
、>=
、==
和!=
都是有效的(通过totally_ordered_with
的约束)。
但为什么? 为什么我们要使用std::ranges::less{}
而不是std::less{}
? 只有在定义了其他比较运算符(而不仅仅是<
一个)的情况下,我们才希望less{}
的实际情况是什么?
只有在定义了其他比较运算符(而不仅仅是 < 一个)的情况下,我们才希望减少 {} 的实际情况是什么?
并非 Ranges 库的所有内容都纯粹基于“实用”的内容。 其中大部分是关于使语言和库具有逻辑意义。
概念作为一种语言特性使标准库有机会定义 object 特性的有意义组合。 从纯粹实用的角度来说,说一个类型有一个operator<
是很有用的,它告诉你它可以使用哪些操作。 但它并没有真正说明类型的任何意义。
如果一个类型是完全有序的,那么这在逻辑上意味着您可以使用任何比较运算符来比较该类型的两个对象。 在全序的思想下, a < b
和b > a
是等价的语句。 因此,如果代码仅限于提供总顺序的类型,则应该允许该代码使用任一语句。
ranges::less::operator()
不使用除<
以外的任何运算符。 但是这个totally_ordered
仅限于对完全有序概念建模的类型。 存在此约束是因为ranges::less
用于:比较完全有序的类型。 它可以有一个更窄的约束,但这将抛弃全排序提供的任何意义。
它还可以防止您向用户公开任意实现细节。 例如,假设您有一个模板,它采用某种类型T
并且您想在基于ranges::less
的操作中使用T
。 如果您将此模板限制为仅具有operator<
,那么您已有效地将您的实现置于约束中。 您不再有实现在内部切换到ranges::greater
的自由。 然而,如果您将std::totally_ordered
放在约束中,您将让用户清楚他们需要做什么,同时让自己可以自由使用所需的任何函子。
并且由于operator<=>
存在并且可以很容易地在一个 function 中实现排序运算符,因此没有实际的缺点。 好吧,除了必须在 C++17 和 C++20 上编译的代码。
本质上,您不应该通过仅编写operator<
来编写“有序”的类型。
据我所知,根据提案,这个想法只是简化 function 对象的设计。 std::less
是一个模板 class ,它需要一个模板参数并表示同质比较。 此模板参数可以省略,默认为允许异类比较的std::less<void>
。 争论似乎是同构案例是不必要的,因为它可以通过异构方法很好地处理,因此可以大大简化设计,并且根本不需要 class 模板。
至于为什么需要除operator<
之外的其他运算符,我不完全确定。 我最好的猜测是,这只是在 C++ 中定义的两个可能不同的类型之间的总顺序的一部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.