2.1.1
有件事需要注意,当把函数对象传入到线程构造函数中时,需要避免“最令人头痛的语法解 析”(C++’s most vexing parse, 中文简介)。如果你传递了一个临时变量,而不是一个命名的变 量;C++编译器会将其解析为函数声明,而不是类型对象的定义。
例如:
std::thread my_thread(background_task());//
这里相当与声明了一个名为my_thread的函数,这个函数带有一个参数(函数指针指向没有参 数并返回background_task对象的函数),返回一个 std::thread 对象的函数,而非启动了一个 线程。 使用在前面命名函数对象的方式,或使用多组括号①,或使用新统一的初始化语法②,可以避 免这个问题。使用lambda表达式也能避免这个问题。
如下所示:
std::thread my_thread((background_task())); // 1
std::thread my_thread{background_task()}; // 2
2.2
默认参数要拷贝到线程独立内存中,即使参数是引用的形式,也可以在新线程中进 行访问
void f(int i, std::string const& s);
std::thread t(f, 3, "hello");
char buffer[1024]; // 1
sprintf(buffer, "%i",some_param);
std::thread t(f,3,buffer); // 2
t.detach();
std::thread t(f,3,std::string(buffer));//使用std::string,避 免悬垂指针