![](/img/trans.png)
[英]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.