如何在 C++11 lambda 中通过移动(也称为右值引用)捕获?
我正在尝试写这样的东西:
std::unique_ptr<int> myPointer(new int);
std::function<void(void)> example = [std::move(myPointer)]{
*myPointer = 4;
};
原文由 user406009 发布,翻译遵循 CC BY-SA 4.0 许可协议
如何在 C++11 lambda 中通过移动(也称为右值引用)捕获?
我正在尝试写这样的东西:
std::unique_ptr<int> myPointer(new int);
std::function<void(void)> example = [std::move(myPointer)]{
*myPointer = 4;
};
原文由 user406009 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
C++14 中的广义 lambda 捕获
在 C++14 中,我们将拥有所谓的 广义 lambda 捕获。这将启用移动捕获。以下将是 C++14 中的合法代码:
另请注意,如果您需要将对象从 lambda 移动到其他函数,则需要使 lambda
mutable
。广义的 lambda 捕获在某种意义上更为通用,捕获的变量可以用如下任何方式初始化:
在 C++11 中,这还不可能,但有一些涉及辅助类型的技巧。幸运的是,Clang 3.4 编译器已经实现了这个很棒的功能。如果保持 最近的发布速度,编译器将在 2013 年 12 月或 2014 年 1 月发布。
更新: Clang 3.4 编译器 于 2014 年 1 月 6 日发布,具有上述功能。
移动捕获的解决方法
这是一个辅助函数的实现
make_rref
它有助于人工移动捕获这是一个在我的 gcc 4.7.3 上成功运行的函数的测试用例。
这里的缺点是
lambda
是可复制的,当复制rref_impl
的复制构造函数中的断言时失败导致运行时错误。以下可能是更好甚至更通用的解决方案,因为编译器会捕获错误。在 C++11 中模拟广义 lambda 捕获
这里还有一个想法,关于如何实现广义 lambda 捕获。函数
capture()
(其实现在下面找到)的使用如下:这里
lambda
是一个仿函数对象(几乎是一个真正的 lambda),它在传递给capture()
std::move(p)
capture
的第二个参数是一个 lambda,它将捕获的变量作为参数。当lambda
用作函数对象时,传递给它的所有参数将作为捕获变量之后的参数转发给内部 lambda。 (在我们的例子中,没有进一步的参数需要转发)。本质上,与之前的解决方案相同。以下是capture
的实现方式:第二种解决方案也更简洁,因为如果捕获的类型不可复制,它会禁用复制 lambda。在第一个解决方案中,只能在运行时使用
assert()
进行检查。