thread和bind传递引用参数
在使用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