这个答案解释了如何在C++14中在lambda中移动捕获变量。
但是一旦你在lambda中移动捕获了一个不可复制的对象(比如std::unique_ptr
),你就不能复制lambda本身。
如果你可以移动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()>&’
...我想这意味着我尝试移动lambda失败了。
clang++
给出了类似的错误。
我尝试明确地移动lambda(尽管它是一个临时值),但没有帮助。
编辑:下面的答案已经充分解决了上述代码产生的编译错误。作为另一种方法,只需将唯一指针的目标值“释放”到一个可以被复制的std::shared_ptr
中。(我没有将此作为答案写出来,因为那会假设这是一个XY问题,但理解为什么unique_ptr
不能在转换为std::function
的lambda中使用的根本原因是很重要的。)
编辑2:非常有趣的是,我刚意识到auto_ptr
实际上在这里会做正确的事情!据我所知,它的行为基本上类似于unique_ptr
,但允许复制构造代替移动构造。