我在lambda中有一个lambda,在for循环中有一个loop变量参数.当我运行它时,我希望输出数字0-9.但由于它是一个lambda,x不会立即得到评估.
for( int x = 0; x < n; ++x)
{
vec.push_back(thread{[&x](){
m.lock();
cout << x << endl;
m.unlock();
}});
}
Run Code Online (Sandbox Code Playgroud)
输出:
0
3
3
9
Run Code Online (Sandbox Code Playgroud)
等等
其他语言的解决方案是创建一个临时变量,
for( int x = 0; x < n; ++x)
{
int tmp = x;
vec.push_back(thread{[&tmp](){
m.lock();
cout << tmp << endl;
m.unlock();
}});
}
Run Code Online (Sandbox Code Playgroud)
但这似乎不起作用.
请参阅接收错误参数的线程
奖金:
在我寻找答案的过程中,我偶然发现了这个问题, 概括了C++ 11 Threads类以使用lambda ,它建议不使用会使迭代器无效的容器.为什么会这样?
Die*_*ühl 11
指定捕获时,可以选择按值捕获和按引用捕获.您已选择通过引用捕获.通过引用捕获意味着lambda函数内的变量指的是同一个对象.这意味着对此变量的任何更改都将被共享,您还需要确保引用的对象在lambda函数的生命周期内保持不变.
你可能想要通过值捕获.为此,您可以替换捕获规范以成为[=]或变为[x].后者确保只有x前者可以访问其他变量才能访问.
顺便说一句,我建议不要使用lock()和unlock()明确,而是使用其中一个锁定防护装置.有了这个,你的循环体看起来像这样:
vec.push_back(std::thread{[x](){
std::lock_guard<std::mutex> kerberos(m);
std::cout << x << "\n";
}});
Run Code Online (Sandbox Code Playgroud)
如果要复制,请按值而不是按引用捕获参数:
vec.push_back(std::thread{[x](){
m.lock();
std::cout << x << std::endl;
m.unlock();
}});
Run Code Online (Sandbox Code Playgroud)
这将复制xlambda对象创建时的值(而不是在线程启动时).
在我寻找答案的过程中,我偶然发现了这个问题,概括了C++ 11 Threads类以使用lambda,它建议不使用会使迭代器无效的容器.为什么会这样?
因为它讨论的是直接使用pthreads库的完全不同的实现.您正在使用std::thread,它旨在使用C++.
| 归档时间: |
|
| 查看次数: |
4250 次 |
| 最近记录: |