2017-06-22 52 views
0

當我使用函數生成一個新線程(std::thread)時,函數 的參數是通過值 - 而不是通過引用。std ::線程參數(值與常數)

所以,如果我定義函數的引用參數(int& nArg) 我的編譯器(MinGW的4.9.2)輸出錯誤(在compilian-suaeli類似 「丟失的拷貝構造函數」我想;-)

但是,如果我讓參考參數const(const int& nArg)它不抱怨。

有人可以解釋一下嗎?

+10

相信與否,有些人能夠閱讀並理解你所謂的「compilian-suaeli」,所以請在問題中包含完整的錯誤信息。順便說一句,也有人可以閱讀代碼,所以請添加[mcve] – user463035818

+0

我不懷疑它。有了那個術語,我的意思是典型的編譯器消息對尋找原因沒有幫助。 – nji9

+0

您應該能夠以英文獲得錯誤輸出,例如在環境中設置LC_ALL = C。 –

回答

0

如果你想通過參考,你必須將它包裝到std::reference_wrapper感謝std::ref。像:

void my_function(int&); 
int my_var = 0; 
std::thread t(&my_function, std::ref(my_var)); 
+0

是的,謝謝,我發現了我自己;-)但是我想知道爲什麼它在引用const時引用它。 – nji9

+0

看看[線程](http://en.cppreference.com/w/cpp/thread/thread/thread),*「線程函數的參數是通過值移動或複製」*,所以有臨時的,並且不能綁定到非** const **引用。 – Jarod42

+0

沒有抱怨的編譯器,如果我做void my_function(const int&); int my_var = 0; std :: thread t(&my_function,my_var); – nji9

0

std::thread的參數被使用一次。

實際上,它將它們存儲在std::tuple<Ts...> tup中。然後它執行f(std::get<Is>(std::move(tup))...)

傳遞std::get右值tuple意味着它可以自由地從元組中的值或右值引用字段中獲取狀態。沒有元組是一個右值,它反而給它一個參考。

除非你使用reference_wrapper(即std::ref/std::cref),傳遞給std::thread的值存儲作爲std::tuple。這意味着您調用的函數將傳遞一個右值到std::tuple中的值。

右值可以綁定到const&而不是&

現在,上面的std::tuple是一個實現細節,一個想象的實現std::thread。標準中的措辭更加鈍化。


爲什麼標準說這會發生?通常,您不應將&參數綁定到將立即丟棄的值。該函數認爲它正在修改調用者可以看到的內容;如果該值將立即丟棄,則這通常是調用者的錯誤。

const&另一方面,參數綁定到將立即丟棄的值,因爲我們將它們用於提高效率的目的不僅僅用於參考目的。

或者,粗略的,因爲

const int& x = 7; 

是合法

int& x = 7; 

不是。第一個是const&到一個邏輯上被丟棄的對象(它不是由於引用生存期延長,但它在邏輯上是臨時的)。