![](/img/trans.png)
[英]How to return a std::function that contains a std::unique_ptr from a generalized lambda capture in C++14?
[英]How to capture a unique_ptr in a std::function
我需要將unique_ptr
移動到std::function
閉包。 我在 C++14 中使用廣義 lambda 捕獲。
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)] { };
此處的示例將使這看起來有效。
請注意, 這里的答案只是重復了 isocpp.org 上的示例。
我可以移動到shared_ptr
如下:
shared_ptr<Foo> s = move(ptr);
但這會產生另一個問題,因為我需要從我的 lambda 中調用一個需要unique_ptr
的函數,而且我無法將shared_ptr
轉換回unique_ptr
。
是否可以在std::function
捕獲unique_ptr
?
std::function
是一個類型擦除對象,支持復制存儲的對象。
當您在 lambda 中存儲std::unique_ptr
時,該 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 中。
解決方案非常簡單。 不是將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)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.