[英]boost operator totally_ordered composed of less_than_comparable and equality_comparable
[英]Why Sortable concept requires totally ordered value type, while std::sort only requires “less than” comparable?
在关于概念N3701的最新论文中 ,有以下关于sort
算法的示例:
template<typename Cont>
requires Sortable<Cont>()
void sort(Cont& cont)
其中Sortable
概念定义为
template<typename T>
concept bool Sortable()
{
return Permutable_container<T>() && Totally_ordered<Value_type<T>>();
}
其中Totally_ordered
,毫不奇怪,被定义为
template<typename T>
constexpr bool Totally_ordered()
{
return Weakly_ordered<T>() && Equality_comparable<T>();
}
然后将Equality_comparable
定义为
template<typename T>
constexpr bool Equality_comparable()
{
return requires(T a, T b) {
{a == b} -> bool;
{a != b} -> bool;
};
}
我没有找到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;
};
}
底线,在这个定义中,如果我想对std::vector<T>
进行排序,我需要T来提供所有比较运算符<
, <=
, >
, >=
, ==
, !=
。 但是,在C ++的整个生命周期中, std::sort
只需要提供operator <
! 这是关于std::sort
cppreference所说的:
按升序对[first,last]范围内的元素进行排序。 不保证保持相等元素的顺序。 第一个版本使用operator <来比较元素 ,第二个版本使用给定的比较函数对象comp。
那么,这意味着在未来的C ++中使用概念,对于类型为std::vector<T>
v
,其中T
仅提供operator<
, std::sort(v.begin(), v.end())
将编译,而std::sort(v)
不会? 这听起来很疯狂。
我在Eric Niebler的当前range-v3实现中检查了这个,它就像我描述的那样工作。 除非提供所有运算符,否则代码不会编译。
另见相关讨论: https : //github.com/ericniebler/range-v3/issues/271
Concepts TS没有概念化标准库。 这只是一个例子; 而已。
Ranges TS版本的sort
需要Sortable
,它将其比较类默认为std::less<>
。 但是,似乎std::less<>::operator()
对其参数类型强加了TotallyOrdered
要求。 这就是它的来源。 在P0021R0中有一个关于此的说明(PDF) :
[编者注:删除[utility.arg.requirements]中的表[lessthancomparable]。 将LessThanComparable替换为TotallyOrdered( 确认这是一个突破性更改,使类型要求更严格 )。 用对[concepts.lib.compare.totallyordered]的引用替换对[lessthancomparable]的引用
强调补充说。 围绕此问题的一般性问题似乎暂时搁置 ,等待其他语言功能(例如仅基于operator<
或某些运算符隐式创建所有其他运算operator<
)。
您可以简单地使用(理智)版本的比较函数。 或者你可以使用std::sort
迭代器版本,它不会使用任何类型的概念。
还应该注意的是,随着C ++ 20中“太空船运营商” 的引入 (我们最早可以看到Ranges TS被纳入标准),这整个讨论实际上没有实际意义。 一个简单的auto operator<=>(const MyType &) = default;
在课堂上宣布,突然你的类型完全有序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.