thread和bind傳遞引用引數
阿新 • • 發佈:2021-12-16
在使用std::thread時遇到問題,程式碼簡化如下:
#include <iostream> #include <thread> #include <string>int main(int argc, char** argv){ auto show = [](const std::string& str) { std::cout << str << std::endl; }; std::string str{"Hello world"}; auto th = std::thread(show, str); th.join(); return 0;
}
編譯失敗。主要原因是在thread的執行函式中傳遞了引用引數,thread為了保證傳入引數的生命週期有效,避免無意識使用引用,對引數加了限制。將引用改為傳值,上面程式碼可正常編譯通過。
如果確定需要引用,可使用std::ref和std::cref對引用進行包裝:
#include <iostream> #include <thread> #include <string> int main(int argc, char** argv) { auto show = [](const std::string& str) { std::cout<< str << std::endl; }; std::string str{"Hello world"}; auto th = std::thread(show, std::cref(str)); th.join(); return 0; }
在bind中,可正常傳遞飲用引數,但是由於無法判斷傳遞進來的引數是否一直有效,對於函式中的引用引數也採取的傳值方式。驗證程式碼如下:
#include <functional> #include <iostream> using namespace std; void increase(int& num1, int& num2) { std::cout << "in func increase start: num1 = " << num1 << "; num2 = " << num2 << std::endl; ++num1; ++num2; std::cout << "in func increase end: num1 = " << num1 << "; num2 = " << num2 << std::endl; } int main(int argc, char** argv) { int num1 = 1, num2 = 1; std::cout << "befor call func: num1 = " << num1 << "; num2 = " << num2 << std::endl; auto func = bind(increase, num1, std::ref(num2)); func(); std::cout << "after call func: num1 = " << num1 << "; num2 = " << num2 << std::endl; return 0; }
執行結果如下:
befor call func: num1 = 1; num2 = 1 in func increase start: num1 = 1; num2 = 1 in func increase end: num1 = 2; num2 = 2 after call func: num1 = 1; num2 = 2
結果分析:
在bind中,num1是傳值,increase函式中改變的只是num1等副本,對main中的原始值沒有影響;
num2通過ref包裝,傳遞等是引用,increase函式中遞增後,main中的值發生改變
參考連結:
https://www.cnblogs.com/jingyg/p/5970359.html
https://blog.csdn.net/lmb1612977696/article/details/81543802