首頁 >後端開發 >C++ >如何透過C Lambda表達式中的Move高效捕獲物件?

如何透過C Lambda表達式中的Move高效捕獲物件?

DDD
DDD原創
2024-12-09 07:19:07716瀏覽

How Can I Efficiently Capture Objects by Move in C   Lambda Expressions?

Lambda 表達式中的移動捕獲

簡介

在C 中,透過移動捕獲,也稱為右值引用,允許用於將物件的所有權有效地轉移到lambda 表達式。在需要在 lambda 中明確管理物件資源的情況下,此技術特別有用。

C 14 中的通用 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 中移動捕獲的解決方法

在 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 捕獲

在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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn