2011-08-21 44 views
7

前段時間有人告訴我,實施雙元運營商的通常模式需要最後的move作爲回報。C++ 0x T operator +(const T&,T &&)模式,仍然需要移動?

Matrix operator+(const Matrix &a, Matrix &&b) { 
    b += a; 
    return std::move(b); 
} 

但是,現在是在return編譯器可以把返回值作爲一個暫時的,那麼這將不會是必要的特殊規則 - 一個簡單的return b就足夠了。

但話又說回來,b在這個函數中有一個,因此,它的左值 - 這阻礙了編譯器到m認爲這是一個臨時的,並且需要move

這是最新版本的C++ 0x標準的情況嗎? 我們需要move來實現上述模式?

+2

根據[這個答案](http://stackoverflow.com/questions/6009004/are-value-parameters-implicitly-moved-when通過值返回/ 6009012#6009012),'std :: move'不是必須的。 – fredoverflow

+2

雖然它可以有所不同,該參數是一個'矩陣&&'而不是'矩陣'... – fredoverflow

+2

它*是*複雜的,是的。是的,我認爲你是對的。如果它的a *值參數*像'Matrix'那麼你就有一個單獨的原始拷貝 - 一個溫度。編譯器知道你可以從中抓取。用'Matrix &&'我不*確定 - – towi

回答

7

您需要明確std::move在這個例子中,因爲b不是非易失性自動對象的名稱。附圖12.8 [class.copy]/P31/B1:

  • 在返回語句與類返回類型,一個功能時 表達式是一個非易失性自動對象的名稱(其他 比的函數或catch子句參數)用相同的CV- 不合格類型作爲函數返回類型時,複製/移動操作 可以通過直接構建自動物體插入 函數的返回值被省略
+2

啊,引用不是對象。我認爲你應該強調「對象」而不是「自動」(或兩者)。 – fredoverflow

+0

我認爲** automatic **在這裏是正確的,因爲它將(粗略地?精確地?)翻譯爲「局部變量」。 – towi

0

我不知道爲什麼這個函數按值返回。不應該像下面這樣返回Matrix&&嗎?

Matrix&& operator+(const Matrix &a, Matrix &&b) { 
    b += a; 
    return std::move(b); 
} 

這有額外的好處,x1 + x2 + x3 + ... + xn創建最多一個暫時的,這是很重要的,如果矩陣恰好是堆棧中分配(因爲它當時沒有獲得來自移動)。

我認爲簽名應該是這樣的:

Matrix&& operator+(Matrix &&a,  Matrix &&b ); 
Matrix&& operator+(const Matrix &a, Matrix &&b ); 
Matrix&& operator+(Matrix &&a,  const Matrix &b); 
Matrix operator+(const Matrix &a, const Matrix &b); 
+0

不可以。您不應該返回'&&'。這意味着,你返回提到其中一個參數的地方,你不能控制它來自哪裏(「不要接受躺在街上的東西」)。如果你返回一個'Matrix',你可以在其中一個參數的內容中「移動」,並以完美的性能完成相同的效果。另外,你不需要在'(&&,&&)'上重載:你在那裏編寫的代碼將和'(&,&&)'或'(&&,&&)'中的代碼相同。如果你省去'(&&,&&)'重載,那麼編譯器會選擇其中一個。您只需要3次重載。 – towi

+0

towi:返回參數之一的參數有什麼問題?我認爲只回復一個臨時引用是一個問題。 – Clinton

+1

@towi:另外,你有什麼證據證明'(&&,&&)'過載是不需要的?我相信http://ideone.com/qf3Rn表明它是必需的。 – Clinton

相關問題