void hello(const string& str2)
{while(1){cout << str2 << end;}
}void main()
{{string str1("123");std::thread t(hello, str1);t.detach();}Sleep(9999);
}
首先我们分析一段这段代码,局部变量str1作为引用传参,传入线程t,在hello里面不停输出str2。主线程等待999s。这时str1肯定已经在主线程析构了,那么线程报错了吗?
答案是没有,调试发现,传入的str2和str1的地址并不相同。
让我们再写一个测试程序
struct MyTest
{MyTest(){cout << "constructor" << endl;i = 0;}~MyTest(){cout << "destructor" << endl;}MyTest(MyTest&){cout << "copy construct" << endl;}int i;
};void hello(MyTest& my2)
{while(1){cout << my2.i++ << end;}
}void main()
{{MyTest my1;std::thread t(hello, my1);t.detach();}Sleep(9999);
}
猜猜输出了什么?
constructor
copy construct
copy construct
copy construct
destructor0
destructor
destructor1
2
3
嘿嘿,发现了,这调用的都是拷贝构造函数,所以给C++线程对象thread传递引用会调用拷贝构造函数,而不会引用传参。
原因是,thread传入的参数并不知道你传入的是引用还是右值,需要用std::ref显式地指明。