簡體   English   中英

為什么 C++20 中的空結構沒有隱式宇宙飛船運算符?

[英]Why do empty structs in C++20 do not have implicit spaceship operator?

動機:有時我使用 std::variant 來實現“花式”枚舉,其中一些枚舉狀態可以攜帶 state。

現在,如果我想將<=>用於我的變體,它要求我的空結構已定義 <=>。 這對我來說似乎有點奇怪,因為如果類型有 0 位 state 則該類型的所有實例都是相同的。

完整示例

#include <compare>
#include <iostream>
#include <variant>

struct Off{
    // without this the code does not compile
    auto operator<=>(const Off& other) const = default;
};

struct Running{
    int rpm=1000;
    auto operator<=>(const Running& other) const = default;
};

using EngineState = std::variant<Off, Running>;

int main()
{
    EngineState es1, es2;
    es1<=>es2;
}

默認的比較運算符是選擇加入,而不是選擇退出。

如果它是選擇退出的,那么它可以將無法編譯的代碼轉換為具有某種未知含義的編譯代碼。 標准委員會試圖盡可能地保持向后兼容性。

其原因最終歸結為:“可比較”類型意味着什么?

可比較的類型首先是帶有的類型。 這種類型的對象帶有一個在某種意義上有意義的值。

你的例子就是這樣一種情況。 本質上,您正在使用variantOff來使用替代值來增加Running的值狀態。 我自己會使用optional<Running> ,但無論如何。 Off是一種在您的問題空間中合法具有價值的類型。 它的價值是“不運行”。

大多數空的 object 類型並非如此。 根據該術語的任何定義, std::in_place_t沒有有意義的“價值”。 它是一個標簽,用於將就地構造調用分派給某些類型的構造函數。 要求將一個實例與另一個實例進行比較是沒有意義的。

但是,您希望在默認情況下使其具有可比性。

很多無狀態類型沒有以面向值的方式使用。 用於分派到重載集的標簽、用於提供對全局資源的基於對象的訪問的類型等。這並不是說沒有面向值的空類型。 但是它們太多了,單方面宣布它們都應該默認具有可比性似乎很奇怪。

此外,以價值為導向是可比性的必要條件,但它並不是充分的。 對於明顯以價值為導向的類型,我們沒有默認的可比性。

聚合類型具有所有公共成員,因此沒有什么能阻止任何人隨時在其中插入任何值。 他們顯然是以價值為導向的。

然而聚合類型在默認情況下是不可比較的。 他們也不應該。 並非所有可以假設比較的東西都應該進行比較。

即使可以對特定的值集合進行排序,允許對它們進行排序是否有意義? 這取決於收藏。 如果我有 2D 點類型,可以訂購。 應該嗎? 我可以理解平等測試,但全面的可比性? 你可以定義它,但這樣的比較有意義嗎?

這是只有類型的創建者才能回答的問題。 因此,我們強迫類型的創建者詢問他們想要什么。

沒有成員只是有一些公共成員的特例。

暫無
暫無

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

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