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

cod*_*der 7 c++ lambda pass-by-reference stdthread

继这个问题之后:可以通过参考传递一段时间吗?

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

// 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();
    });
}
Run Code Online (Sandbox Code Playgroud)

这被称为:

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) });
}
Run Code Online (Sandbox Code Playgroud)

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

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

thread()noexcept; (1)(自C++ 11以来)

thread(thread && other)noexcept; (2)(自C++ 11起)

template <class Function,class ... Args> explicit thread(Function && f,Args && ... args); (3)(自C++ 11起)

thread(const thread&)= delete; (4)(自C++ 11以来)

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

template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
Run Code Online (Sandbox Code Playgroud)

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

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

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

mol*_*ilo 8

一个临时的确被移动了,但它是"内在的",是争论的std::thread.

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

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