引自 The C++ Programming Language(作者:Bjarne Stroustrup),第1213页
\n\n线程构造函数是
\nvariadic templates(\xc2\xa728.6)。这意味着要将引用传递给线程构造函数,我们必须使用引用包装器 (\xc2\xa733.5.1)。例如:
\nRun Code Online (Sandbox Code Playgroud)\nvoid my_task(vector<double>& arg);\nvoid test(vector<double>& v)\n{\n thread my_thread1 {my_task,v}; //oops: pass a copy of v\n thread my_thread2 {my_task,ref(v)}; // OK: pass v by reference\n thread my_thread3 {[&v]{ my_task(v); }}; // OK: dodge the ref() problem\n // ...\n}\n
问题是variadic templates通过引用目标函数传递参数没有问题。
例如:
\nvoid g(int& t)\n{\n}\n\ntemplate <class... T>\nvoid f(T&&... t)\n{\n g(std::forward<T>(t)...);\n}\n\nint main()\n{\n int i;\n f(i);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n按值传递的唯一原因是标准要求在参数上std::thread …
为什么在没有任何专门化的情况下将通用 lambda 传递给 std::thread() 是合法的,而另一方面,这对于函数模板来说是非法的。
下面演示了我的查询。
#include <thread>
template <class T>
void f(T t)
{
}
int main()
{
std::thread t([](auto i){}, 1); // Works
std::thread t(f, 1); // Doesn't work
std::thread t(f<int>, 1); // Works
t.join();
return 0;
}
Run Code Online (Sandbox Code Playgroud)