C++中,临时Lambda表达式能否通过引用传递?(在MSVC/Windows上可以,但在GCC/Linux上不行)

5
假设我有以下代码片段:
// global variable
std::thread worker_thread;

// Template function
template <typename Functor>
void start_work(Functor &worker_fn)  // lambda passed by 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([do_work](int value){ do_work(value) });
}

我开始在MSVC2012上进行开发。这一切都编译得很好,似乎也能正常工作。但是当我转到Linux平台上的gcc编译器时,我得到了以下(缩写)错误:

no known conversion for argument 1 '...__lambda3' to '...__lambda3&'

我的问题:

  • 所以,从错误信息来看,我认为lambda表达式是一个临时变量,因此无法通过引用传递 - 是这样吗?
  • 另外,有什么想法可以解释为什么这会在MSVC上工作吗?它是否自动修复了我的代码?
1个回答

7

MSVC 在这里违背了标准,它允许匿名临时对象绑定到非 const 的左值引用。你可以使用 /Za 编译器标志(“禁用语言扩展”)或 MSVC2017 更强的选项 /permissive- 关闭此功能。

C++ 标准一直清楚地规定,匿名临时变量只能绑定到 const 引用。


@code_fodder; 嗯,对于函数参数使用const引用会修复gcc编译。 - Bathsheba
太好了,谢谢啊:)...不过要等8分钟才能标记答案...:( - code_fodder
1
做了一个小小的追求完美的更正。希望你不介意。 - StoryTeller - Unslander Monica
1
不,它将在函数调用的持续时间内保持在作用域中。 - Bathsheba
1
@code_fodder: “即使使用线程”,如果在lambda捕获中使用引用,需要确保原始对象在lambda运行时处于范围内。” - Bathsheba
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接