2011-07-28 42 views
3

只是一定要很好地理解什麼是引擎蓋下...問題是在代碼中評論移動語義和變量終身綁定時左值右值來引用

void test(int && val) 
    { 
     val=4; 
    }//val is destroyed here ? 

int main() 
{ 
    int nb; 
    test(std::move(nb)); 
    //undefined behavior if I reference here nb ? 
    std::cout << nb; 
    nb=5; 
    std::cin.ignore();  
} 
+1

'void main()'... –

回答

3

移動的值保留在有效但未指定的狀態。就我所知,這基本上意味着它可能包含任何值,但它必須包含一些值,並且訪問它是合法的和已定義的行爲。

1

這不是不確定的行爲,因爲你從來沒有實際從val移動到你的函數中。 std::move僅僅將nb變成右值。這實際上只有在你有其他模糊的test過載時纔有意義。

0
//val is destroy here ? 

相同的答案,如果參數類型是const int& val

//undefined behavior if I reference here nb ? 

號但是沒有指定打印出來的值。這不同於「未定義的行爲」,這意味着任何事情都可能發生。如果它是未定義的行爲將意味着您的磁盤可能會被重新格式化。

+2

你能解釋爲什麼在這種情況下未指定打印值嗎?我會預料它會被詳細說明,因爲在函數內部沒有實際的移動操作。 –

+2

我相信這種行爲的確有明確的規定;它將'nb'設置爲4。不過,我可能錯了,所以你可以澄清爲什麼它會有一個不明確的價值? – templatetypedef

+0

我明顯地解釋了這個問題。如果您不執行整個程序分析,則未指定要移動的對象的值。在這種情況下,我特意在分析'main'時忽略了'test()'的定義。 –

3

你必須明白,右值對某物的引用不會神奇地移動該值。它所做的只是使得可以對臨時對象進行非const引用。

此參考在您的示例中與正常參考沒有區別,因爲您在此處沒有任何臨時對象。你是必須讓「行動」發生的人。

E.g.如果你定義你的int值爲0,那麼你的int就是空的,並且你編寫了一個接受右值引用的函數,將它消耗並將傳遞值設置爲0,那麼你將前面的值「移出」你的int值。調用此函數後,它將包含0。但那是因爲這樣定義它。

現在,對於整數來說這沒什麼意義,但想象你正在處理一個指向大塊內存的指針。

+0

「你必須明白,某個參數的參數不會神奇地移動該值」,的確如此 – Guillaume07

+0

@Guillaume我很抱歉如果我低估了你的專業知識,但是你的問題「val在這裏被摧毀了嗎?對我來說沒有多大意義。 Val是一個引用,所以是的,引用val在那個時候被銷燬,但是val引用的變量繼續存在,直到它超出變量的作用域或直到它爲臨時對象創建的表達式的「;」 。 – Fozi

0

有關std :: move的詳細說明,請參閱here。除非你沒有開始使用移動構造函數,否則你將無法有效地使用這個新功能。另外,我認爲對於沒有開銷的基本類型來說它沒有任何意義。