内循环 Lambda

2024-02-03

我在 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(使用前将#替换为@)

内循环 Lambda 的相关文章