我在 for 循环中有一个 lambda,其中循环变量参数在 lambda 中。当我运行它时,我期望输出数字 0-9。但由于它是 lambda,因此 x 不会立即求值。
for (int x = 0; x < n; ++x)
{
vec.push_back(thread{[&x]() {
m.lock();
cout << x << endl;
m.unlock();
}});
}
Output:
0
3
3
9
etc.
其他语言的解决方案是创建一个临时变量,
for (int x = 0; x < n; ++x)
{
int tmp = x;
vec.push_back(thread{[&tmp]() {
m.lock();
cout << tmp << endl;
m.unlock();
}});
}
但这似乎不起作用。
see 线程接收错误参数 https://stackoverflow.com/questions/12324204/threads-receiving-wrong-parameters
Bonus:
在寻找答案的过程中,我偶然发现了这个问题泛化 C++11 Threads 类以使用 lambda https://stackoverflow.com/questions/8382918/generalizing-c11-threads-class-to-work-with-lambda建议不要使用会使迭代器无效的容器。
为什么会这样呢?
当您指定捕获时,您可以在按值捕获和按引用捕获之间进行选择。您已选择通过引用捕获。通过引用捕获意味着 lambda 函数内的变量引用同一个对象。这意味着对此变量的任何更改都将被共享,并且您还需要确保引用的对象在 lambda 函数的生命周期内保持不变。
您可能想通过值来捕获。为此,您可以将捕获规范替换为[=]
或成为[x]
。后者确保只有x
可以访问,而前者则允许访问其他变量。
顺便说一句,我推荐not using lock()
and unlock()
明确地,而是使用其中一个锁卫。这样,循环体将如下所示:
vec.push_back(std::thread{[x](){
std::lock_guard<std::mutex> kerberos(m);
std::cout << x << "\n";
}});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)