【发布时间】:2018-04-23 14:00:22
【问题描述】:
接着这个问题:can-a-temperary-lambda-by-passed-by-reference?
我有固定码sn-p:
// 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)(C++11 起)
thread(thread&& other) noexcept; (2)(C++11 起)
模板
显式线程( Function&& f, Args&&... args ); (3)(C++11 起) 线程(常量线程&)=删除; (4)(C++11 起)
所以我假设构造函数 3 被调用:
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
我很难理解这里写的内容,但它看起来会尝试移动 lambda &&,我认为这对于临时变量是可以的。
那么我在我的代码 sn-p 中所做的事情是危险的(即 ref 超出范围)还是正确的(即温度已移动并且一切正常)?还是都没有??
另一种方法是只传递我的值(制作副本),在这种情况下无论如何都不是那么糟糕。
【问题讨论】:
-
按承诺升级。完整的答案高于我的工资等级。
-
你有一个悬空引用。
-
问题是问是否可以将
const &传递给std::thread的临时对象,并且可以。但这不是你在做什么。相反,这里的问题是您在 lambda 中通过引用捕获了一个临时对象,这不是一回事,在这种情况下也不行。 -
简而言之,lambda 可能会被正确移动,但它捕获的东西不会。作为一个骗子,我认为 lambdas 只不过是花哨的函数对象。
-
@code_fodder 考虑将
worker_fn设为转发引用 (Functor&& worker_fn) 并使用std::forward初始化捕获。
标签: c++ lambda pass-by-reference stdthread