分配給類別類型的右值引用:已解決的悖論
在C 領域,左值和右值之間的區別至關重要。左值表示具有可以修改的記憶體位置的對象,而右值則表示不能修改的臨時對像或常數。然而,一個有趣的程式碼片段提出了關於這個基本分歧的問題:
class Y {
public:
explicit Y(size_t num = 0) {}
};
int main() {
Y(1) = Y(0); // Here lies the enigma!
return 0;
}
為什麼這段程式碼可以編譯?建構函數傳回的右邊值不是短暫的,因此不適合賦值嗎?
理解這個悖論的關鍵在於 C 中的隱式賦值運算子。當沒有為類別明確定義賦值運算子時,編譯器會合成預設賦值運算子。至關重要的是,這個合成運算子在某些情況下可以適用於右邊值。
這就是顯式關鍵字發揮作用的地方。在給定的範例中,Y 類別沒有聲明賦值運算符,因此編譯器會產生一個。 Explicit 關鍵字可防止右邊值的隱式轉換,但不會阻止合成賦值運算子套用於右邊值。
因此,在我們的程式碼中,合成賦值運算子:
Y& Y::operator=(Y const&);
或
Y& Y::operator=(Y&);
可以用左側的右值Y(1) 呼叫。即使 Y(1) 是右邊值,這也允許賦值繼續進行。
為了防止臨時物件賦值,可以使用引用限定符 (&) 明確聲明賦值運算子:
class Y {
public:
explicit Y(std::size_t num = 0);
Y& operator=(Y const&) & = default;
};
在這種情況下,賦值運算子將不會被合成,嘗試指派給右邊值將導致編譯錯誤。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3