operators c運算子 - 什麼是C++中的<=>運算符?




c和c ++運算子 (4)

當我試圖了解C ++運算符時,我偶然發現了cppreference.com上一個奇怪的比較運算符* ,其表格如下所示: “好吧,如果這些是C ++中的常見操作符,我更好地學習它們”,我想。 但是我所有試圖闡明這個謎團的嘗試都是失敗的。 即使在這裡,在堆棧溢出我沒有在我的搜索運氣。

<=>C ++之間有關係嗎?

如果有的話,這個操作員究竟做了什麼?

*與此同時,cppreference.com更新了該頁面,現在包含有關<=>運營商的信息。


Answers

2017-11-11年11月2017-11-11日,ISO C ++委員會採納了Herb Sutter針對<=>“飛船”三向比較運算符的提議,將其作為添加到C ++ 20中的新特性之一。 在標題為一致比較 Sutter的論文中,Maurer和Brown展示了新設計的概念。 有關該提案的概述,請參閱以下文章摘錄:

如果a <b ,則表達式a <=> b返回比較<0的對象,如果a> b則比較> 0 ,如果a和b相等/相等,則比較== 0

常見的情況:為了使用成員語義編寫類型為Y的類型X的所有比較,只需編寫:

auto X::operator<=>(const Y&) =default;

高級案例:要為您的類型X寫入Y類型的所有比較,只需編寫帶Y的 操作符<=> ,如果需要,可以使用= default獲取成員語義,然後返回相應的類別類型:

  • 如果你的類型自然支持< ,則返回_ordering ,我們將高效地生成對稱的<><=> ===!= ; 否則返回_equality ,我們將高效地生成對稱==!=
  • 返回strong_如果對於你的類型a == b暗示f(a)== f(b) (可替換性,其中f只讀取可以使用公共常量成員訪問的比較顯著狀態),否則返回weak_

比較類別

五個比較類別被定義為std:: types,每個都有以下預定義的值:

+--------------------------------------------------------------------+
|                  |          Numeric  values          | Non-numeric |
|     Category     +-----------------------------------+             |
|                  | -1   | 0          | +1            |   values    |
+------------------+------+------------+---------------+-------------+
| strong_ordering  | less | equal      | greater       |             |
| weak_ordering    | less | equivalent | greater       |             |
| partial_ordering | less | equivalent | greater       | unordered   |
| strong_equality  |      | equal      | nonequal      |             |
| weak_equality    |      | equivalent | nonequivalent |             |
+------------------+------+------------+---------------+-------------+

這些類型之間的隱式轉換定義如下:

  • strong_ordering的值{ lessequalgreater }隱式轉換為:
    • weak_ordering值{ lessequivalentgreater }
    • partial_ordering的值{ lessequivalentgreater }
    • 具有價值的strong_equality { unequalequalunequal }
    • 具有價值的weak_equality { nonequivalentequivalentnonequivalent }
  • 具有值{ weak_orderingequivalentgreater }的weak_ordering隱式轉換為:
    • partial_ordering的值{ lessequivalentgreater }
    • 具有價值的weak_equality { nonequivalentequivalentnonequivalent }
  • partial_ordering的值{ lessequivalentgreaterunordered }隱式轉換為:
    • 具有價值的weak_equality { nonequivalent equivalentnonequivalentnonequivalent equivalentnonequivalent nonequivalent }
  • 具有值{ equalstrong_equality }的strong_equality隱式轉換為:
    • 具有價值的weak_equality { equivalentweak_equality }

三方比較

介紹<=>標記。 在舊的源代碼中,字符序列<=>標記為<=> 。 例如, X<&Y::operator<=>需要添加一個空格來保留其含義。

可重載操作符<=>是一個三向比較函數,其優先級高於< ,低於<< 。 它返回一個可以與0進行比較的類型,但允許其他返回類型以支持表達式模板。 在語言和標準庫中定義的所有<=>運算符返回上述5個std:: comparison類型之一。

對於語言類型,提供了以下內置的<=>相同類型的比較。 除非另有說明,否則所有內容均為constexpr 。 這些比較不能通過標量促銷/轉換進行異構調用。

  • 對於bool ,整數和指針類型, <=>返回strong_ordering
  • 對於指針類型,允許不同的cv-qualifications和derived-to-base轉換來調用一個同構的內置<=> ,並且有內置的異構operator<=>(T*, nullptr_t) 。 只有指向同一對象/分配的指針才是常量表達式。
  • 對於基本浮點類型, <=>返回partial_ordering ,並且可以通過將參數擴大到更大的浮點類型來異構地調用。
  • 對於枚舉, <=>返回與枚舉的基礎類型的<=>
  • 對於nullptr_t<=>返回strong_ordering並始終產生equal
  • 對於可複制數組, T[N] <=> T[N]返回與T<=>相同的類型,並執行詞典元素比較。 其他數組沒有<=>
  • 對於void ,沒有<=>

這個答案是“正在建設中”。 為了更好地理解該操作員的內部工作原理,請閱讀原文。


自引用的網頁發生變化以來,此答案已變得無關緊要

cppreference.comcppreference.com已損壞。 當天正在進行大量編輯,不同部分不同步。 當我看到它的狀態是:

在頁面頂部,它列出了當前存在的比較運算符(在C ++ 14中)。 那裡沒有<=>

在頁面的底部,他們應該列出相同的操作員,但他們愚蠢並增加了​​這個未來的建議。

gcc不知道a <= > b (還有-std=c++14 ,永遠不會),所以它認為你的意思是a <= > b <=> a <= > b 。 這是錯誤信息的解釋。

如果你從現在起五年後嘗試同樣的事情,你可能會得到一個更好的錯誤信息,像<=> not part of C++14.


這被稱為三路比較運算符

根據P0515提案:

有一個新的三方比較操作符<=> 。 如果a < b ,則表達式a <=> b返回比較<0的對象,如果a > b則比較>0 ,如果ab相等/相等,則比較==0

要為您的類型編寫所有比較,只需編寫返回相應類別類型的operator<=>

  • 如果您的類型自然支持< ,則返回一個_ordering ,並且我們將高效地生成<><=>===!= ; 否則返回一個_equality ,我們將高效地生成==!=

  • 如果你的類型為a == b則返回強a == b暗示f(a) == f(b) (可替換性,其中f只讀取使用非私有常量接口訪問的比較顯著狀態),否則返回弱。

cppreference.com說:

三向比較運算符表達式具有這種形式

lhs <=> rhs   (1)  

該表達式返回一個對象

  • 如果lhs < rhs則比較<0
  • 如果lhs > rhs則比較>0
  • 如果lhsrhs相等/相等,則比較==0

在Java類型中,當賦值操作右側的表達式類型可以安全地提升為賦值左側的變量類型時,將自動執行轉換。 因此我們可以安全地分配:

 byte -> short -> int -> long -> float -> double. 

反之亦然。 例如,我們不能自動將long轉換為int,因為第一個需要比第二個更多的存儲,因此信息可能會丟失。 要強制執行此類轉換,我們必須執行顯式轉換。
類型 - 轉換





c++ operators c++-faq c++20 spaceship-operator