c move函式的疑惑?

時間 2021-05-06 02:42:37

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) 不是,所以是不同的。

關於all 函式的一些疑惑?

dram 那你覺得應該返回什麼呢?丟擲異常?返回 None?我認為這就和 x y 在 x 或 y 為 0 的時候丟擲異常 返回 None 之類的一樣奇怪 不明白為什麼 python 設計的時候 x 0 要返回 x all 要根據基本法來的。根據大家的期望,all 應該有如下性質 只考慮列表的 boo...

最近的疑惑?

阿殊迦 因果見解就是善有善報,惡有惡報。遵循五條原則 1.業決定2.自作自受3.未作業不受4.已作業不失5.業增長廣大。乙個不恰當的比方,過去的業像是一紙文憑,給你乙個開局。如果工作後積極進取,有很大可能超出文憑界定的範圍。比如二本的平均表現只能到某個水平,但你很努力,又聰明,所以超越了就業天花板。...

轉行的疑惑?

Horton Chen 想從學徒做起,那你的發展方向是技師,例如焊接師傅 銑床師傅,跟你想做的模具設計機械設計方向不對。學徒發展成設計師的概率很小,別看很多設計師都當過學徒,那是組織安排去培養的。機械是很不適合外行人轉入的。做機械設計要對數學 靜力學 動力學 材料力學 材料學 運動學 工藝學 互換性...