向线程函数传递函数

2020-05-08  本文已影响0人  _ace2
#include<thread>
void fun(int i,std::string const& str) {
    return;
}

int main()
{
    std::string s("hellos");
    std::thread t(fun,3,s);
    t.join();
    system("pause");
    return 0;
}

向函数传参,默认参数都会被拷贝到线程的独立内存中,函数内访问的都是被拷贝的副本,即使参数是引用的形式,如上面会产生一个s的副本,然后赋给str,str并不是s的引用。

如何传递一个非常量引用?

void fun(int i,std::string & str);
std::thread t(fun,3,s);

fun函数第二个参数期待传入一个引用,但是 std::thread 的构造函数并不知晓;构造函数无视函数期待的参数类型,并盲目的拷贝已提供的变量s。不过,在代码会将参数以右值的方式进行拷贝传递,这是为了照顾到那些只能进行移动的类型,而后会以右值为参数向fun函数传参。因为函数期望的是一个非常量引用作为参数,而非一个右值,所以会在编译时出错。对于熟悉 std::bind 的开发者来说,问题的解决办法是显而易见的:可以使用 std::ref 将参数转换成引用的形式。如下可以正确调用:

void fun(int i,std::string & str);
std::thread t(fun,3,std::ref(s));

传递常量引用:

void fun(int i,std::string const& str);
std::thread t(fun,3,std::ref(s));
void fun(int i,std::string const& str);
std::thread t(fun,3,std::cref(s));

两种写法都有在构造线程时明确引用传递,且在fun函数参数都加了const权限,都达到了在fun内不能修改str的效果。

错误写法:

void fun(int i,std::string & str);
std::thread t(fun,3,std::cref(s));

这种写法会在编译时出错,在构造线程时明确常量引用传递,但在fun函数参数没有加const权限,把一个常量传给一个非const变量是会报错的。

用类函数作为线程函数

 class A
 {
 public:
      fun(int i);
 };
A a;
std::thread t(&A::fun,&a,1); 

新线程将a.fun()作为线程函数(注意一定要是public函数);a的地址作为指针对象提供给函数。线程构造函数的第三个参数就是成员函数的第一个参数,以此类推。

上一篇 下一篇

猜你喜欢

热点阅读