1樓:Mike Dog
實際上,左右值本質是資料所有權的轉移。在資料所有權轉移過程中,有且僅有乙個引用或者物件可以擁有資料的所有權。
所謂右值引用,不過是宣告「這個引用需要擁有資料的所有權」。而 std::move(x) 這乙個函式呼叫是乙個許可權轉移宣告,表達「可以放棄 x 中資料的所有權」,因此它能產生右值。
而普通的 int && i 並不能代表所有權可轉移,因此直接使用並不是乙個右值。
這一點在 int 這個常量型別上體現得不太明顯,我用 vector 來舉個例子:
vector
&&vec1
=std
::vector
;// OK, std::vector 是個右值, 所有權可以直接傳遞給 vec
const
vector
&vec2
=vec1
;// OK,左值引用不需要擁有所有權
vector
&&vec3
=vec1
;// ERROR, vec3 需要所有權, 但是 vec1 沒有放棄
vector
&&vec4
=std
::move
(vec1
);// OK, std::move 放棄了 vec1 的所有權。
在這個例子中,儲存 的資料段的 owner 永遠只有乙個,從純粹的右值物件std::vector, 轉移到 vec1,再轉移到 vec4. 最後這個資料段的釋放,將由 vec4 完成。以上
2樓:
一般來講,有名稱的變數(具名變數)都是左值,int&& i = 0表明i是乙個右值引用,它繫結到乙個右值上,i本身不是右值,0才是右值,你可以對i取位址;
2. 因為i是左值,所以將乙個右值繫結到乙個左值上是不合法的,所以int&& j = i是不對的,會編譯錯誤
3. 將乙個左值強制轉為乙個右值可以用std::move操作,move並不會對傳入的變數做任何修改,它只會將其強制轉換為乙個右值,因此將乙個右值引用繫結到乙個右值上是合法的
3樓:
int && j = X; 這裡X必須不能取位址int &&j = i; 錯誤是因為i可以取位址&istd::move是乙個函式,作為函式的返回值是不能取位址的,因此可以。注意任何函式返回值都可以用T &&繫結:
int && i = foo()
更多細節請移步: https://www.
4樓:邁步從頭越
int&& j=std::move(i) 應該也是無效的,右值引用實際上就是乙個告訴編譯器的符號,讓它去匹配右值引數的過載進行呼叫,這個符號存在的意義是表面該資源在scope裡面的下文中不會再被用到了,所以傳入的方法裡面可以破壞性的使用它。
而任何在等號左邊的變數都天生是左值,因為變數的存在意義就是再次被下文引用,如果該資源還會被下問使用,則它傳入的方法裡面不能破壞性使用它,通常要做個copy,因此編譯器會幫你匹配左值引用的方法。
另外要知道的是右值引用的全部作用也只是幫你匹配過載方法,並不涉及真正的管理資源本身的歸屬,你依然可以在右值引用的過載方法裡面做資源copy而非破壞性使用的,甚至如果沒有右值引用的過載,右值會自動匹配到左值引用的方法來呼叫。但是如果是那樣做,那就失去了右值引用的意義。
在來說move,原來右值只屬於inline在方法引數上的直接構造或者方法返回值,比如 builder(string())這種,任何變數做為引數則都沒法呼叫右值引用的過載,比如string s;builder(s)但move給了你乙個機會也就是說你非常清楚這個變數在後面不會再用了,你可以用builder(move(s))來強行掉builder(string&& s)過載。
5樓:lv jing
首先 int&&表示的是乙個右值引用
如果乙個右值一旦被繫結到乙個引用(無論左值引用還是右值引用),那麼該引用就是乙個左值(具名右值引用是左值)
std::move(i)是乙個表示式,每個表示式都有其自己型別。std::
move(i)的型別是乙個不具名的右值引用(不具名右值引用是右值)。題主一定要注意變數i的左右值屬性和表示式std::move(i)的左右值屬性是完全不同的。
6樓:
i是乙個右值引用型別的左值。
std::move(i)是乙個右值引用型別的右值。
型別(type)和值型別(value category)在兩個維度上。
i的型別(type)是右值引用,因為加了&&。
i的值型別(value category)是左值,因為它有名字。
通過std::move以後,型別(type)沒變,還是右值引用,但值型別(value category)成了右值,因為人家欽定,cast的結果,只要型別(type)不是左值引用或函式的右值引用,那麼值型別(value category)就是右值。
7樓:土地測量員
但是我看書,move其實就乙個型別轉換而已,返回的還是int&& 型別的物件,難道不還是左值嗎?
因為move雖然是型別轉換,但是它實際上是通過乙個函式來實現的,比如說:
template
_Tp> constexpr typename std:: remove_reference <_Tp>:: type &&move (_Tp &&__t )noexcept 而這個函式返回值是個右值引用,即typename std::remove_reference<_Tp>::type&&,而c++規定了呼叫返回值是右值引用的函式的表示式是右值。 (可能有點拗口,逃 The following expressions are xvalue expressions: a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as std::move(x); ...Value categories 8樓:機犬 i 是 && 的左值,可以看成 && &,引用摺疊成 &; 而 std::move 返回的是 && 的右值,可以看成 && &&,引用摺疊成 &&。 9樓:d41d8c 不存在『引用型別的物件』。引用不是物件。 是不是lvalue,看的是表示式的形式(雖然也有其他因素)。 i 在形式上是變數名,而 std::move(i) 不是,所以是不同的。 dram 那你覺得應該返回什麼呢?丟擲異常?返回 None?我認為這就和 x y 在 x 或 y 為 0 的時候丟擲異常 返回 None 之類的一樣奇怪 不明白為什麼 python 設計的時候 x 0 要返回 x all 要根據基本法來的。根據大家的期望,all 應該有如下性質 只考慮列表的 boo... 阿殊迦 因果見解就是善有善報,惡有惡報。遵循五條原則 1.業決定2.自作自受3.未作業不受4.已作業不失5.業增長廣大。乙個不恰當的比方,過去的業像是一紙文憑,給你乙個開局。如果工作後積極進取,有很大可能超出文憑界定的範圍。比如二本的平均表現只能到某個水平,但你很努力,又聰明,所以超越了就業天花板。... Horton Chen 想從學徒做起,那你的發展方向是技師,例如焊接師傅 銑床師傅,跟你想做的模具設計機械設計方向不對。學徒發展成設計師的概率很小,別看很多設計師都當過學徒,那是組織安排去培養的。機械是很不適合外行人轉入的。做機械設計要對數學 靜力學 動力學 材料力學 材料學 運動學 工藝學 互換性...關於all 函式的一些疑惑?
最近的疑惑?
轉行的疑惑?