簡體   English   中英

三向比較運算符與減法有何不同?

[英]How is the three-way comparison operator different from subtraction?

在C ++ 20中有一個新的比較運算符<=> 但是我認為在大多數情況下,簡單的減法效果很好:

int my_strcmp(const char *a, const char *b) {
    while (*a == *b && *a != 0 && *b != 0) {
        a++, b++;
    }
    // Version 1
    return *a - *b;
    // Version 2
    return *a <=> *b;
    // Version 3
    return ((*a > *b) - (*a < *b));
}

它們具有相同的效果。 我無法理解其中的差異。

運算符解決了減法帶來的數值溢出問題:如果從接近INT_MIN的負數中減去一個大的正數,則會得到一個不能表示為int ,從而導致未定義的行為。

雖然版本3沒有這個問題,但它完全缺乏可讀性:以前從未見過這個技巧的人需要一些時間才能理解。 <=>運算符也修復了可讀性問題。

這只是新運營商解決的一個問題。 Herb Sutter的Consistent比較文件第2.2.3節討論了<=>與其他數據類型的使用,其中減法可能會產生不一致的結果。

以下是減法不適用的一些情況:

  1. unsigned類型。
  2. 導致整數溢出的操作數。
  3. 用戶定義的類型沒有定義operator - (可能因為它沒有意義 - 可以定義一個順序而不定義距離的概念)。

我懷疑這份清單並非詳盡無遺。

當然,至少可以為#1和#2提供變通方法。 但是operator <=>的意圖是封裝丑陋。

這里有一些有意義的答案,但Herb Sutter在他的論文中特別說:

<=>適用於類型實現者:在運算符<=>的實現之外的用戶代碼(包括通用代碼)幾乎不應該直接調用<=>(已經在其他語言中發現為良好實踐);

因此,即使沒有區別,運算符的要點也不同:幫助類編寫者生成比較運算符。

減法運算符和“太空船”運算符之間的核心差異(根據Sutter的提議)是重載operator-給你一個減法運算符,而重載operator<=>

  • 為您提供6個核心比較運算符(即使您將運算符聲明為default :無需編寫代碼!);
  • 聲明您的班級是否具有可比性,是否可以排序,以及該訂單是全部還是部分(Sutter提案中的強弱);
  • 允許異構比較:您可以重載它以將您的類與任何其他類型進行比較。

其他差異在於返回值: operator<=>將返回類的enum ,該類指定類型是否可排序以及排序是強還是弱。 返回值將轉換為-1,0或1(盡管Sutter為返回類型留出空間以指示距離,如strcmp所做的那樣)。 在任何情況下,假設-1,0,1返回值,我們最終將在C ++中獲得真正的signum函數 signum(x) == x<=>0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM