c – 将const引用传递给临时/匿名lambda到std :: thread构造函数是否安全?

继续这个问题: can-a-temperary-lambda-by-passed-by-reference?

我有一个固定的代码片段:

// global variable
std::thread worker_thread;

// Template function
template <typename Functor>
void start_work(const Functor &worker_fn)  // lambda passed by const ref
{
    worker_thread = std::thread([&](){
        worker_fn();
    });
}

这被称为这样:

void do_work(int value)
{
    printf("Hello from worker\r\n");
}

int main()
{
    // This lambda is a temporary variable...
    start_work([](int value){ do_work(value) });
}

这似乎有效,但我担心将临时lambda传递给线程构造函数,因为线程将运行,但函数start_work()将返回,temp-lambda将超出范围.

但是我正在查看定义的std :: thread构造函数

thread() noexcept; (1) (since C++11)

thread( thread&& other ) noexcept; (2) (since C++11)

template< class Function,class… Args >
explicit thread( Function&& f,Args&&… args ); (3) (since C++11)

thread(const thread&) = delete; (4) (since C++11)

所以我假设构造函数3被调用

template< class Function,class... Args >
explicit thread( Function&& f,Args&&... args );

我很难理解这里写的是什么,但看起来它会试图移动lambda&&我认为对于临时变量是好的.

那么我在我的代码片段中做了什么危险(即ref超出范围)或正确(即临时移动,一切都很好)?还是两个?

另一种方法就是传递我的价值(制作副本),在这种情况下无论如何都不是那么糟糕.

解决方法

临时确实被移动但它是“内部”,std :: thread的参数.

该临时文件持有对“外部”临时文件的引用,start_work的参数,以及在start_work返回后其生命周期结束的引用.

因此,您的“内部”lambda对象包含对在执行期间可能存在或可能不存在的对象的引用,这是非常不安全的.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...