簡介
在C 中,透過移動捕獲,也稱為右值引用,允許用於將物件的所有權有效地轉移到lambda 表達式。在需要在 lambda 中明確管理物件資源的情況下,此技術特別有用。
在 C 14 中,通用 lambda 捕獲提供了一個優雅的解決方案用於移動捕捉。借助此功能,可以聲明一個使用移動語義按值捕獲變數的 lambda 表達式:
using namespace std; auto u = make_unique<some_type>(some, parameters); go.run([u = move(u)] { do_something_with(u); });
此方法將 u 的所有權移至 lambda,確保資源得到適當釋放。此外,如果需要將物件移出 lambda,則必須將 lambda 宣告為可變。
在 C 11 中,移動捕獲並不直接支援。然而,有一些技術可以模擬這種行為。一種方法是使用輔助函數建立右值參考(rref):
template <typename T> struct rref_impl { rref_impl() = delete; rref_impl(T &&x) : x(std::move(x)) {} // ... (remaining implementation) }; template<typename T> rref_impl<T> make_rref(T &&x) { return rref_impl<T>{std::move(x)}; }
使用此輔助函數,可以透過在lambda 中移動來擷取物件:
unique_ptr<int> p{new int(0)}; auto rref = make_rref(std::move(p)); auto lambda = [rref]() mutable -> unique_ptr<int> { return rref.move(); };
請注意, lambda 被聲明為可變的,以允許修改捕獲的右值引用。
在C 11 中模擬廣義lambda 捕獲的另一種方法是使用自訂類別來捕獲變數並提供一種將其移出lambda 的方法:
template <typename T, typename F> struct capture_impl { T x; F f; // ... (remaining implementation) }; template <typename T, typename F> capture_impl<T,F> capture(T &&x, F &&f) { return capture_impl<T,F>(std::forward<T>(x), std::forward<F>(f)); }
此類可用於透過move 擷取變數並提供呼叫lambda的方法:
unique_ptr<int> p{new int(0)}; auto lambda = capture(std::move(p), [](unique_ptr<int> &p) { return std::move(p); });
與與先前的方法相比,如果捕獲的類型不可複製,則該 lambda 不可複製。這可以防止複製 lambda 時出現潛在錯誤。
以上是如何透過C Lambda表達式中的Move高效捕獲物件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!