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

posted @ 2021-12-16 13:09  亚九  阅读(788)  评论(0编辑  收藏  举报