任务通常需要处理数据,我们可以将数据(或指向数据的指针或引用)作为参数传递给任务,例如:
void f(vector<double>& v); //处理v的函数struct F{ //处理v的函数对象vector<double>& v;F(vector<double>& vv):v{vv}void operator()(); //调用运算符,见3.4.3节}int main(){vector<double> some_vec{1,2,3,4,5,6,7,8,9};vector<double> vec2{1,2,3,4,5,6,7,8,9};thread t1{f,some_vec}; //f(some_vex)在一个独立线程中执行thread t2{F{vec2}}; //F{vec2}()在一个独立线程中执行t1.join();t2.join();}
显然,F{vec2}将一个指向参数(一个向量)的引用保存在F中。F现在就可以使用向量了,并希望在它运行的时候其他任务不会访问vec2——将vec2以传值方式传递就可以消除这个风险。
上面代码用{f,some_vec}初始化一个线程,它使用了 thread的可变参数模板构造函数,接受一个任意的参数序列(见28.6节)。编译器检查第一个参数(函数或函数对象)是否可用后续的参数来调用,如果检查通过,就构造一个必要的函数对象并传递给线程。因此,F::operator()与f()执行相同的算法,两个任务的处理大致相同:它们都为 thread构造了一个函数对象来执行任务。
