我需要将unique_ptr
移至std::function
闭包。我在C ++ 14中使用generalized lambda captures。
auto ptr = make_unique<Foo>();
// Works.
auto lambda = [p = move(ptr)] { };
// This does not compile.
std::function<void()> func = [p = move(ptr)] { };
它正在尝试将Lambda捕获内容复制而不是移动到std::function
中。相关错误是:
copy constructor of '' is implicitly deleted because field '' has a deleted copy
constructor
std::function<void()> func = [p = move(ptr)] { };
示例here将使此方法似乎可行。
请注意,answer here仅重复了isocpp.org上的示例。
我可以按照以下步骤移至shared_ptr
:
shared_ptr<Foo> s = move(ptr);
但这带来了另一个问题,因为我需要在lambda中调用一个期望unique_ptr
的函数,并且无法将shared_ptr
转换回unique_ptr
。
是否可以在unique_ptr
中捕获std::function
?
答案 0 :(得分:1)
解决方案非常简单。与其将unique_ptr
移到shared_ptr
上,不如使用shared_ptr
指向unique_ptr
:
auto holder = make_shared<unique_ptr<Foo>>(move(ptr));
std::function<void()> func = [holder] { MyFunction(move(*holder)); };
注意:在我的用例中,func
仅被调用一次,所以move(*holder)
可以。
答案 1 :(得分:0)
std::function
是一种类型擦除对象,它支持复制存储的对象。
将std::unique_ptr
存储在lambda中时,该lambda不支持被复制。
因此std::function
非常正确。它是一种可以复制的类型,当传入某些内容时,就可以确定如何复制它。 “我无法复制”不是有效答案;所有std::function
都可以复制。
有两种常见方法可以解决此问题。首先,将std::function
的状态存储在某种std::shared_ptr
中。其次,您编写或找到一个非复制std::function
,然后改用它。
更多的“现代” std::function
替换库支持许多有用的东西:
出于各种特殊目的,我个人需要以上每一项。
然后,当您不需要复制可调用对象并编译代码时,将使用moveonly_function<void()>
。
但是,这可能对于您现在的需求来说太重了。
template<class F>
auto make_shared_function( F&& f ) {
return
[pf = std::make_shared<std::decay_t<F>>(std::forward<F>(f))]
(auto&&...args)->decltype(auto)
{
return (*pf)( decltype(args)(args)... );
};
}
现在无论何时遇到此问题:
// This does not compile.
std::function<void()> func = make_shared_function([p = move(ptr)] { });
并且可调用对象的状态现在存储在共享的ptr中。