標籤:

C++的std::thread是怎麼進行參數傳遞的?

如下面的測試代碼,為什麼t1, t2, t3, t4輸出會是那樣的呢?是背後是怎樣的參數傳遞機制形成的呢?

class String
{
public:
String(const char* cstr) { std::cout &<&< "String()" &<&< std::endl; } // 1 String(const String v) { std::cout &<&< "String(const String v)" &<&< std::endl; } // 2 String(const String v) noexcept { std::cout &<&< "String(const String v)" &<&< std::endl; } // 3 String operator=(const String v) { std::cout &<&< "String operator=(const String v)" &<&< std::endl; return *this; } }; void test(int i, String const s) {} int main() { String s("hello"); std::cout &<&< "----------------" &<&< std::endl; // 輸出 1, 2 std::thread t1(test, 3, s); t1.join(); std::cout &<&< "----------------" &<&< std::endl; // 輸出 2, 2 std::thread t2(test, 3, std::move(s)); t2.join(); std::cout &<&< "----------------" &<&< std::endl; // 只輸出 1 std::thread t3(test, 3, "hello"); t3.join(); std::cout &<&< "----------------" &<&< std::endl; // 無輸出 std::thread t4(test, 3, std::ref(s)); std::cout &<&< "----------------" &<&< std::endl; t4.join(); }


按照這個輸出,那麼thread應該是先複製你的參數,然後在線程啟動的時候把他們move進你的test函數里。


thread 是模板,參數的形式是所謂的 forwarding reference(或 universal reference),所以傳參給 thread 的構造函數時,如果參數是左值,則參數被 copy 到內部,如果傳的參數是右值,則 move,無論如何 thread 內部都(暫時)保留了參數的一個 copy,然後內部傳給用戶的函數時,直接 move.


我就多嘴一句, 這個行為標準並沒有規定, 所以屬於實現細節, 不同版本的標準庫可能是不一樣的.


推薦閱讀:

怎麼正確書寫C++高階函數?
你怎麼看 C++11(新的 C++ 標準)裡面的變化?
我們需不需要跟進C++11/14?
double 和 long double 有哪些區別?

TAG:C | C11 |