C 中的std move函式到底是做什麼的?

時間 2021-06-27 12:54:00

1樓:eiilpux17

move的作用只是讓編譯器優先選擇引數型別是右值引用的建構函式或者方法,由開發者在建構函式或方法中對物件動態申請的記憶體做操作,具體做了什麼並不重要。

這裡明確是動態申請的,new或者malloc,這些記憶體只是由物件來管理,需要通過delete或free釋放,因此開發者可以在方法裡決定記憶體的所有權交給誰,交給其他物件或者什麼都不做或者直接釋放。而屬於物件本身的記憶體仍舊是不可「移動」的,比如有個int[10]這樣的成員,這部分是處於物件本身的生命週期內。

如果沒有右值引用引數型別的建構函式或方法,就會匹配const引用型別,因為以前將亡值或者臨時物件不允許被修改。正因為無法修改,所以對於上面說的由物件動態管理的記憶體就必須進行深度拷貝以保證記憶體安全,這就是以前的開銷,右值引用就是提供了一種可修改的途徑。

至於編譯器對move後的物件記憶體有什麼額外的優化,沒有深究。

2樓:劉豐偉

template

T>typename

remove_reference

::

type

&&move(T

&&t)move的原型如上,就是做了乙個型別轉換,如果不用move,也可以用一下方式代替:

static_cast&&>(t);

3樓:naive

其實move本身相當於什麼都沒乾,只是轉換成右值,不過轉換為右值後,就能使用移動構造了。移動構造對不同型別效果不一樣,對於int,int i=std::move(j),後面j還是原來的值,但對於vector,vector a=std::

move(b),b裡的資料都移動到了a,也就是b為空了,當然不能繼續使用。

4樓:szouc

題主可能被「右值」和「左值」表面符號誤導了。

a glvalue (「generalized」 lvalue) is an expression whose evaluation determines the identity of an object, bit-field, or function;

a prvalue (「pure」 rvalue) is an expression whose evaluation either

......

an xvalue (an 「eXpiring」 value) is a glvalue that denotes an object or bit-field whose resources can be reused;

「左值」和「右值」的全稱是「左值表示式」和「右值表示式」,看到了嗎?an expression whose ... 。

他們不是結果,只是由運算子和運算元組成的表示式。

符號 a 是左值表示式,它繫結了乙個儲存區塊(物件),對該物件擁有所有權。此時 a 想主動放棄對這個物件的擁有權,符號右值表示式 std::move(a) 的作用就是讓 a 繫結的物件沒有所有者,也就是沒有符號繫結了。

試想沒有符號繫結你以後再怎麼利用這個物件?所以把 std::move(a) 具體稱為「將亡值表示式」。

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);

......

In particular, std::move produces an xvalue expression that identifies its argument t. It is exactly equivalent to a static_cast to an rvalue reference type.

上面的引用告訴我們 std::move 是乙個函式,它的作用類似強制型別轉換(把乙個表示式轉換為另乙個型別的表示式),該函式的返回值 std::move(x) 是乙個「將亡值表示式」。

Also, the standard library functions called with xvalue arguments may assume the argument is the only reference to the object; if it was constructed from an lvalue with std::move, no aliasing checks are made.

這段告訴我們呼叫 std::move(a) 時,假定a 是物件的唯一引用。

最後,既然是主動放棄所有權,那就不要再使用 a 引用物件了。

最後的最後,物件是不具有左值右值屬性的,表示式再怎麼從右值變成左值,從左值變成右值,和物件沒有一丁點關係。

5樓:爬樹賊溜的小松鼠

要理解這些細節,首先需要明白最重要的概念move。

C++ move是為了轉移所有權,將快要銷毀的物件轉移給其他變數,這樣可以繼續使用這個物件,而不必再建立乙個一樣的物件。省去了建立新的一樣內容的物件,也就提高了效能。對於某些資源來說,可以改變所有者,但是只能有乙份,move也解決這樣的物件的管理問題。

具體可以看我的專欄寫的關於move的文章。裡面有詳細的講解和生動形象的例子。

6樓:杜紫童

單純的move的確沒啥作用,它通常要配合其他的東西來用。

struct

sample

// 函式2

sample

&operator=(

sample&&)

// 函式3

void

func

()const&{}

// 函式4

void

func

()&&

{}};

當使用的時候,就可以通過move來指明你想呼叫的是哪乙個函式:

samples1,

s2;s1=

s2;// 呼叫函式1s1=

std::

move(s2

);// 呼叫函式2s1.

func

();// 呼叫函式3

std::

move(s1

).func

();// 呼叫函式4

move這個名字有點迷惑人,因為通常我們是想用右值來表達「移動」,而不是用「移動」來表達右值。

單純的move之後的值是可以用的,因為單純的move本身就沒什麼意義。 但是move之後的值,一旦交給他人使用(如上例s1 = std::move(s2)),再使用相應的變數(s2),就是ub了。

但是要讓人分辯這些情況即麻煩又沒什麼意義,乾脆move之後就不讓用,永絕後患。

量子 Liouville 方程中的導數到底是偏導數還是全導數?

已根據 遊傑宇 的回答進行了修改。對之前回答的不仔細道歉。這個方程又名為von Neumann方程。曹昌祺 輻射和廣場的量子統計理論 第五章匯出了量子Liouville方程,用的是全微分符號。此處基於Schrdinger繪景,量子態的隨時間演化。如果用相互作用繪景,則此方程會變為另一種形式,即哈密頓...

矩陣的指數函式到底說的是個啥?

你可以這麼理解。首先指數函式最重要的意義是什麼?其導數是其本身的倍數。這確實非常方便,尤其做微分方程的時候。現在我們想把定義域換成矩陣。我們的目的是構建出f At 使得f At Af At 這也會讓很多計算大大化簡。最後就構建出了這麼個玩意。然後我們還可以證明所有其他符合f At Af At 的函式...

殘差網路ResNet訓練時的目標函式到底是什麼?

李御心 目標函式跟網路是分開的兩個部分。目標函式,是為了達成目標,給網路乙個feedback,讓它學習。網路是達成目標的 魔法 只要知道了最後一層目標函式的導數,扔給網路學就可以了。很多時候我們都認為網路是乙個feature extractor backbone 跟問題本身沒有太大關係。ResNet...