简体   繁体   English

为什么Sortable概念需要完全有序的值类型,而std :: sort只需要“小于”可比性?

[英]Why Sortable concept requires totally ordered value type, while std::sort only requires “less than” comparable?

In the latest paper on concepts N3701 , there is the following example with the sort algorithm: 关于概念N3701最新论文中 ,有以下关于sort算法的示例:

template<typename Cont>
  requires Sortable<Cont>()
void sort(Cont& cont)

where Sortable concept is defined as 其中Sortable概念定义为

template<typename T>
concept bool Sortable()
{
  return Permutable_container<T>() && Totally_ordered<Value_type<T>>();
}

where Totally_ordered , not surprisingly, is defined as 其中Totally_ordered ,毫不奇怪,被定义为

template<typename T>
constexpr bool Totally_ordered()
{
  return Weakly_ordered<T>() && Equality_comparable<T>();
}

and in turn Equality_comparable is defined as 然后将Equality_comparable定义为

template<typename T>
constexpr bool Equality_comparable()
{
  return requires(T a, T b) {
    {a == b} -> bool;
    {a != b} -> bool;
  };
}

I didn't find the definition of Weakly_ordered , but I believe it should look like this (am I right?) 我没有找到Weakly_ordered的定义,但我相信它看起来应该是这样的(我是对的吗?)

template<typename T>
constexpr bool Weakly_ordered()
{
  return requires(T a, T b) {
    {a < b} -> bool;
    {a <= b} -> bool;
    {a > b} -> bool;
    {a >= b} -> bool;
  };
}

Bottom line, in this definition, if I want to sort std::vector<T> , I need T to provide all comparison operators < , <= , > , >= , == , != . 底线,在这个定义中,如果我想对std::vector<T>进行排序,我需要T来提供所有比较运算符<<=>>===!= However, during the whole life of C++, std::sort only required operator < to be provided! 但是,在C ++的整个生命周期中, std::sort只需要提供operator < Here is what cppreference says about std::sort : 这是关于std::sort cppreference所说的:

Sorts the elements in the range [first, last) in ascending order. 按升序对[first,last]范围内的元素进行排序。 The order of equal elements is not guaranteed to be preserved. 不保证保持相等元素的顺序。 The first version uses operator< to compare the elements , the second version uses the given comparison function object comp. 第一个版本使用operator <来比较元素 ,第二个版本使用给定的比较函数对象comp。

So what, does that mean that in future C++ with concepts, for v of type std::vector<T> where T provides only operator< , std::sort(v.begin(), v.end()) will compile, while std::sort(v) will not? 那么,这意味着在未来的C ++中使用概念,对于类型为std::vector<T> v ,其中T仅提供operator<std::sort(v.begin(), v.end())将编译,而std::sort(v)不会? This sounds crazy. 这听起来很疯狂。

I checked this in the current ranges-v3 implementation by Eric Niebler, and it works just like I described. 我在Eric Niebler的当前range-v3实现中检查了这个,它就像我描述的那样工作。 Code does not compile unless all operators are provided. 除非提供所有运算符,否则代码不会编译。

See also related discussion: https://github.com/ericniebler/range-v3/issues/271 另见相关讨论: https//github.com/ericniebler/range-v3/issues/271

The Concepts TS does not conceptualize the standard library. Concepts TS没有概念化标准库。 It was merely an example; 这只是一个例子; nothing more. 而已。

The Ranges TS version of sort requires Sortable , which defaults its comparison class to std::less<> . Ranges TS版本的sort需要Sortable ,它将其比较类默认为std::less<> However, it would seem that std::less<>::operator() imposes the TotallyOrdered requirement on the types of its parameters. 但是,似乎std::less<>::operator()对其参数类型强加了TotallyOrdered要求。 So that's where it comes from. 这就是它的来源。 There's a note about this in P0021R0 (PDF) : P0021R0中有一个关于此的说明(PDF)

[Editor's note: Remove table [lessthancomparable] in [utility.arg.requirements]. [编者注:删除[utility.arg.requirements]中的表[lessthancomparable]。 Replace uses of LessThanComparable with TotallyOrdered ( acknowledging that this is a breaking change that makes type requirements stricter ). 将LessThanComparable替换为TotallyOrdered( 确认这是一个突破性更改,使类型要求更严格 )。 Replace references to [lessthancomparable] with references to [concepts.lib.compare.totallyordered]] 用对[concepts.lib.compare.totallyordered]的引用替换对[lessthancomparable]的引用

Emphasis added. 强调补充说。 The general issues surrounding this appear to be on-hold , pending other language features (like implicit creation of all other operators based solely on operator< or somesuch). 围绕此问题的一般性问题似乎暂时搁置 ,等待其他语言功能(例如仅基于operator<或某些运算符隐式创建所有其他运算operator< )。

You could simply use a (sane) version of a comparison function. 您可以简单地使用(理智)版本的比较函数。 Or you could just use the std::sort iterator version, which won't use concepts of any kind. 或者你可以使用std::sort迭代器版本,它不会使用任何类型的概念。


It should also be noted that, with the introduction of the "spaceship operator" in C++20 (the earliest we could see the Ranges TS integrated into the standard), this whole discussion effectively becomes moot. 还应该注意的是,随着C ++ 20中“太空船运营商” 的引入 (我们最早可以看到Ranges TS被纳入标准),这整个讨论实际上没有实际意义。 A simple auto operator<=>(const MyType &) = default; 一个简单的auto operator<=>(const MyType &) = default; declaration in the class, and suddenly your type is totally ordered. 在课堂上宣布,突然你的类型完全有序。

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

相关问题 由less_than_comparable 和equality_comparable 组成的boost 运算符totally_ordered - boost operator totally_ordered composed of less_than_comparable and equality_comparable 概念的常量版本作为 requires 子句中的返回类型 - Constant version of a concept as return type in requires clause 为什么std :: vector需要operator = - Why std::vector requires operator = 编写一个最小的自定义运算符:std::sort 需要为我的类型设计 std::__lg - Write a minimal custom operator: std::sort requires std::__lg to be degined for my type 需要 function 通过值或引用返回另一个概念的概念 - Concept that requires a function to return another concept by value or reference C++11:如何使用 lambda 作为类型参数,它需要像 std::less/std::greater 这样的“函子类型”? - C++11: how to use lambda as type parameter, where it requires a "functor type" like std::less/std::greater? 为什么 std::totally_ordered<float> 返回真?</float> - Why does std::totally_ordered<float> return true? 为什么 std::queue 要求元素是可复制的? - Why std::queue requires the element to be copyable? c++ 需要带有反向返回类型概念检查的表达式 - c++ requires expression with inverse return type concept check 为什么std ::比“&lt;”更好? - Why is std::less better than “<”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM