This answer解释了如何在 C++14 中 move 捕获 lambda 中的变量。
但是,一旦您在 lambda 中 move 捕获了一个不可复制的对象(例如 std::unique_ptr
),您就无法复制 lambda 本身。
如果您可以 move lambda,这会很好,但尝试这样做时会出现编译错误:
using namespace std;
class HasCallback
{
public:
void setCallback(std::function<void(void)>&& f)
{
callback = move(f);
}
std::function<void(void)> callback;
};
int main()
{
auto uniq = make_unique<std::string>("Blah blah blah");
HasCallback hc;
hc.setCallback(
[uniq = move(uniq)](void)
{
std::cout << *uniq << std::endl;
});
hc.callback();
}
g++
会产生以下错误(我试图只复制相关行):
error: use of deleted function ‘main()::<lambda()>::<lambda>(const main()::<lambda()>&’
...我认为,这意味着我 move lambda 的尝试失败了。
clang++
给出了类似的错误。
我尝试显式move
lambda(即使它是一个临时值),但这并没有帮助。
编辑: 下面的答案充分解决了上述代码产生的编译错误。对于另一种方法,只需将唯一指针的目标值release
到std::shared_ptr
中,可以 复制。 (我没有写这个作为答案,因为那会假设这是一个 XY 问题,但是 unique_ptr
不能在转换为 的 lambda 中使用的根本原因>std::function
理解起来很重要。)
编辑 2: 好笑的是,据我所知,我刚刚意识到 auto_ptr
实际上会在这里做正确的事情(!)。它的行为本质上类似于 unique_ptr
,但允许复制构造代替 move 构造。
最佳答案
你可以 move lambda,没关系。不过,这不是您的问题,您正在尝试使用不可复制的 lambda 实例化 std::function
。还有:
template< class F >
function( F f );
function
的构造函数确实:
5) Initializes the target with a copy of
f
.
这是因为 std::function
:
satisfies the requirements of CopyConstructible and CopyAssignable.
由于 function
必须是可复制的,因此您放入其中的所有内容也必须是可复制的。而只能 move 的 lambda 不满足该要求。
关于c++ - move lambda : once you've move-captured a move-only type, 如何使用 lambda?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32486623/