簡體   English   中英

為什么C ++左值對象不能綁定到右值引用(&&)?

[英]Why C++ lvalue objects can't be bound to rvalue references (&&)?

移動語義的想法是,您可以從另一個臨時對象(由右值引用引用)中獲取所有內容,並將“所有內容”存儲在對象中。 這有助於避免在單個構造事物足夠的情況下進行深度復制 - 因此您可以在rvalue對象中構造事物,然后將其移動到長壽命對象中。

為什么C ++不允許將左值對象綁定到右值引用? 兩者都允許我更改引用的對象,因此在訪問引用對象的內部方面對我沒有任何區別。

我能猜到的唯一原因是函數重載模糊問題。

但是為什么C ++不允許將左值對象綁定到右值引用?

假設你的意思是“為什么C ++不允許將右值引用綁定到左值對象” :它確實如此。 它不是自動的,所以你必須使用std::move來使它顯式化。

為什么? 因為否則一個無害的函數調用會令人驚訝地破壞你沒想到的東西:

Class object(much,state,many,members,wow);
looks_safe_to_me(object);
// oh no, it destructively copied my object!

Class object(much,state,many,members,wow);
obviously_destructive(std::move(object));
// same result, but now the destruction is explicit and expected

關於破壞性復制的注釋:為什么我說上面的破壞性破壞 ,我並不是說對象析構函數結束它的生命周期:只是它的內部狀態已被移動到一個新實例。 它仍然是一個有效的對象,但不再擁有以前相同的昂貴狀態。


關於術語的說明:讓我們看看我們是否可以清除上面對左值右值等的不精確使用。

引用后代的cppreference

  • 一個左值

    具有身份無法移動的表達式。

    所以,沒有lvalue對象這樣的東西,但是有一個由左值表達式在本地命名(或引用)的對象

  • 右邊

    一個表達式,它是一個prvalue或一個xvalue。 可以從 它可能有也可能沒有身份。

    • prvalue (純rvalue)大致是指一個未命名的臨時對象的表達式:我們不能將我們的左值表達式轉換為這些IIUC中的一個。

    • xvalue (到期值)是

      一個具有身份可以移動的表達式。

      其中明確包含std::move的結果

那么實際發生了什么:

  • 存在一個對象
  • 該對象由左值表達式在本地標識,該表達式無法移動(以保護我們免受意外的副作用)
  • std::move產生一個xvalue表達式(可以從中移動)引用與左值表達式相同的對象
  • 這意味着對象,例如變量(其由左值表達式命名)不能從隱式地移動,並且必須而是明確從經由顯式表達x值移動諸如std::move
  • 匿名臨時值可能已由prvalue表達式引用,並且可以隱式移動

本質上,需要一種機制來區分可以移動的值和不能移動的值(即需要復制)。

允許rvalues和lvalues綁定到左值引用使得這是不可能的。

因此,綁定到右值引用的值可以從(不一定總是要移動,但允許)移動,並且左值可以綁定到左值引用,並且不能從中移動。

std::move用於允許在值類別(到rvalue)之間進行轉換以允許移動發生。

注意; const左值引用( const T& )可以綁定到rvalues(臨時值)和左值,因為引用的對象不能更改(它被標記為const因此無論如何都不能有任何移動)。

有一些歷史(早在C ++的早期)為什么臨時對象無法綁定到非const左值引用開始... ...細節模糊但是有一些推理修改臨時對象沒有有道理 ,因為無論如何它會在當前聲明的最后破壞。 另外,當你實際上沒有修改左值時,你可能會感覺到你正在修改左值 - 代碼的語義可能/將是錯誤的並且是錯誤的。 還有其他原因與地址,文字等相關聯。這是在移動之前,其語義固化,並且是移動及其語義的一些動機。

暫無
暫無

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

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