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

标签 c++ lambda pass-by-reference stdthread

从这个问题开始: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() 将返回并且临时 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 超出范围)还是正确的(即 temp 被移动并且一切正常)?还是两者都不是??

另一种方法是只传递我的值(制作拷贝),在这种情况下这还算不错。

最佳答案

A 临时文件确实被移动了,但它是“内部”临时文件,std::thread 的参数。

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

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

关于c++ - 将对临时/匿名 lambda 的 const 引用传递给 std::thread 构造函数是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49983078/

相关文章:

amazon-web-services - "errorMessage": Task timed out after 3. 00秒尝试连接RDS的AWS Lambda Node.js Lambda函数

C++ 成员函数需要指针,通过引用传递的坏习惯?

c++ - 如何使用 C++ 函数传回一个数字

c++ - 更改垂直标题标题

c++ - 没有大小写的 switch 语句 : or default: labels

android - Fragment 与 Fragment(或 Activity)之间的监听器

c# - 计算具有多个参数的表达式树

C++ 弃用从字符串常量到 'char*' 的转换

python - 如何在 python 子进程之间传递大型 numpy 数组而不保存到磁盘?

c++ - 为什么 const 变量不能通过引用传递?