向线程函数传递函数
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的地址作为指针对象提供给函数。线程构造函数的第三个参数就是成员函数的第一个参数,以此类推。